From 8f6ca4c787210df90e5e371a3cafe54400785252 Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" <15132211195@163.com> Date: Fri, 21 Jul 2023 03:09:56 +0000 Subject: Deploy mate-desktop/mate-netbook to github.com/mate-desktop/mate-netbook.git:gh-pages --- .../index.html | 140 ++ .../report-066e3e.html | 1009 +++++++++++++ .../report-07966d.html | 1009 +++++++++++++ .../report-167811.html | 901 ++++++++++++ .../report-1e2fd5.html | 1009 +++++++++++++ .../report-2eed80.html | 1009 +++++++++++++ .../report-519bf9.html | 1009 +++++++++++++ .../report-5555d9.html | 1009 +++++++++++++ .../report-87f973.html | 1009 +++++++++++++ .../report-8d22c7.html | 901 ++++++++++++ .../report-a2ef3d.html | 1009 +++++++++++++ .../report-b113da.html | 1009 +++++++++++++ .../report-bc0f47.html | 1009 +++++++++++++ .../report-cf4342.html | 849 +++++++++++ .../report-d86ec3.html | 1009 +++++++++++++ .../report-f8083f.html | 1009 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1489 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1273 ++++++++++++++++ .../3.html | 1169 +++++++++++++++ .../index.html | 129 ++ .../stats.html | 108 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-0af285.html | 901 ++++++++++++ .../report-12d4c1.html | 1009 +++++++++++++ .../report-35a7be.html | 1009 +++++++++++++ .../report-436dd6.html | 1009 +++++++++++++ .../report-44b187.html | 1009 +++++++++++++ .../report-6392ce.html | 1009 +++++++++++++ .../report-771039.html | 1009 +++++++++++++ .../report-8f2ecf.html | 1009 +++++++++++++ .../report-9fb331.html | 1009 +++++++++++++ .../report-a656a8.html | 1009 +++++++++++++ .../report-a9552c.html | 901 ++++++++++++ .../report-c24641.html | 1009 +++++++++++++ .../report-c9832e.html | 849 +++++++++++ .../report-d99c84.html | 1009 +++++++++++++ .../report-f5890d.html | 1009 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1489 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1273 ++++++++++++++++ .../3.html | 1169 +++++++++++++++ .../index.html | 129 ++ .../stats.html | 108 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-2e5333.html | 900 ++++++++++++ .../report-326845.html | 1008 +++++++++++++ .../report-336491.html | 1008 +++++++++++++ .../report-372a66.html | 1008 +++++++++++++ .../report-51b5f0.html | 900 ++++++++++++ .../report-522919.html | 1008 +++++++++++++ .../report-5c876e.html | 1008 +++++++++++++ .../report-85e0db.html | 846 +++++++++++ .../report-8d8a6a.html | 1008 +++++++++++++ .../report-a7affc.html | 1008 +++++++++++++ .../report-c01286.html | 1008 +++++++++++++ .../report-c17e44.html | 1008 +++++++++++++ .../report-cc16b0.html | 1008 +++++++++++++ .../report-e2a874.html | 1008 +++++++++++++ .../report-e488cf.html | 1008 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1487 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1271 ++++++++++++++++ .../3.html | 1163 +++++++++++++++ .../4.html | 853 +++++++++++ .../index.html | 132 ++ .../stats.html | 109 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-076df9.html | 1008 +++++++++++++ .../report-153039.html | 1008 +++++++++++++ .../report-26ef1a.html | 1008 +++++++++++++ .../report-295e70.html | 900 ++++++++++++ .../report-3500a3.html | 1008 +++++++++++++ .../report-39c9c4.html | 900 ++++++++++++ .../report-3fa9c9.html | 1008 +++++++++++++ .../report-532882.html | 1008 +++++++++++++ .../report-5fee6c.html | 1008 +++++++++++++ .../report-71d389.html | 1008 +++++++++++++ .../report-75a183.html | 846 +++++++++++ .../report-94cbc5.html | 1008 +++++++++++++ .../report-cba9e3.html | 1008 +++++++++++++ .../report-ecd83c.html | 1008 +++++++++++++ .../report-efae04.html | 1008 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1487 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1271 ++++++++++++++++ .../3.html | 1163 +++++++++++++++ .../4.html | 853 +++++++++++ .../index.html | 132 ++ .../stats.html | 109 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1177 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1231 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 217 +++ .../stats.html | 171 +++ .../style.css | 177 +++ CNAME | 1 + index.html | 46 + 260 files changed, 240563 insertions(+) create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-066e3e.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-07966d.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-167811.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-1e2fd5.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-2eed80.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-519bf9.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-5555d9.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-87f973.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-8d22c7.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-a2ef3d.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-b113da.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-bc0f47.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-cf4342.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-d86ec3.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-f8083f.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/scanview.css create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/sorttable.js create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/0.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/1.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/2.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/3.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/index.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/stats.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/style.css create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/index.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-0af285.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-12d4c1.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-35a7be.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-436dd6.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-44b187.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-6392ce.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-771039.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-8f2ecf.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-9fb331.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a656a8.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a9552c.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c24641.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c9832e.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-d99c84.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-f5890d.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/scanview.css create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/sorttable.js create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/0.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/1.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/2.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/3.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/index.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/stats.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/style.css create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/index.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-2e5333.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-326845.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-336491.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-372a66.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-51b5f0.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-522919.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-5c876e.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-85e0db.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-8d8a6a.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-a7affc.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c01286.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c17e44.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-cc16b0.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e2a874.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e488cf.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/scanview.css create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/sorttable.js create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/0.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/1.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/2.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/3.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/4.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/index.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/stats.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/style.css create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/index.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/0.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/1.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/2.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/3.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/4.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/index.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/stats.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/style.css create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/index.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-05d832.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-1f618a.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-37b917.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-4bda9e.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-678a90.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-6fb882.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-7534c9.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-85a3e8.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-90bf5a.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-aa2062.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-b10f27.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-c2cf20.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e3bdb1.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e9ff85.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-faab40.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/scanview.css create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/sorttable.js create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/0.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/1.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/2.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/3.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/4.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/index.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/stats.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/style.css create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/index.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-05d832.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-1f618a.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-37b917.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-4bda9e.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-678a90.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-6fb882.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-7534c9.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-85a3e8.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-90bf5a.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-aa2062.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-b10f27.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-c2cf20.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-e3bdb1.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-e9ff85.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-faab40.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/scanview.css create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/sorttable.js create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/0.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/1.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/2.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/3.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/4.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/index.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/stats.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/style.css create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/index.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-05d832.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-1f618a.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-37b917.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-4bda9e.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-678a90.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-6fb882.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-7534c9.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-85a3e8.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-90bf5a.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-aa2062.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-b10f27.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-c2cf20.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-e3bdb1.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-e9ff85.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-faab40.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/scanview.css create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/sorttable.js create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/0.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/1.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/2.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/3.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/4.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/index.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/stats.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/style.css create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/index.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-05d832.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-1f618a.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-37b917.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-4bda9e.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-678a90.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-6fb882.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-7534c9.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-85a3e8.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-90bf5a.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-aa2062.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-b10f27.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-c2cf20.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e3bdb1.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e9ff85.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-faab40.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/scanview.css create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/sorttable.js create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/0.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/1.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/2.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/3.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/4.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/index.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/stats.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/style.css create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/index.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-05d832.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-1f618a.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-37b917.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-4bda9e.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-678a90.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-6fb882.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-7534c9.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-85a3e8.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-90bf5a.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-aa2062.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-b10f27.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-c2cf20.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e3bdb1.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e9ff85.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-faab40.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/scanview.css create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/sorttable.js create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/0.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/1.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/2.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/3.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/4.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/index.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/stats.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/style.css create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/index.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-05d832.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-1f618a.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-37b917.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-4bda9e.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-678a90.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-6fb882.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-7534c9.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-85a3e8.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-90bf5a.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-aa2062.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-b10f27.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-c2cf20.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e3bdb1.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e9ff85.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-faab40.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/scanview.css create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/sorttable.js create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/0.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/1.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/2.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/3.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/4.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/index.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/stats.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/style.css create mode 100644 CNAME create mode 100644 index.html diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html new file mode 100644 index 0000000..3832343 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@0ed4f4d3ed32
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 12.0.0 (Fedora 12.0.0-2.fc34) +
Date:Mon Jun 21 21:33:05 2021
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Dead store
Dead nested assignment1
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Dead storeDead nested assignmentmaximus-bind.cmaximus_bind_init4671View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4291View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4541View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4391View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4041View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4091View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4581View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4491View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4141View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4191View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4241View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4441View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4341View Report
+ + diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-066e3e.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-066e3e.html new file mode 100644 index 0000000..b0a96d5 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-066e3e.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 429, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-07966d.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-07966d.html new file mode 100644 index 0000000..1d07b88 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-07966d.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 454, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-167811.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-167811.html new file mode 100644 index 0000000..6e2e309 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-167811.html @@ -0,0 +1,901 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__((noinline)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500
501/* GObject stuff */
502static void
503maximus_app_class_init (MaximusAppClass *klass)
504{
505}
506
507static void
508maximus_app_init (MaximusApp *app)
509{
510 MaximusAppPrivate *priv;
511 WnckScreen *screen;
512
513 priv = app->priv = maximus_app_get_instance_private (app);
514
515 priv->bind = maximus_bind_get_default ();
516
517 was_decorated = g_quark_from_static_string ("was-decorated");
518
519 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
520
521 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
522 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
523 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
524 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
525 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
526 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
527
528 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
529 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
530 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
531 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
532
533 priv->screen = screen = wnck_screen_get_default ();
534 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
535 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
536}
537
538MaximusApp *
539maximus_app_get_default (void)
540
541{
542 static MaximusApp *app = NULL((void*)0);
543
544 if (!app)
545 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
546 NULL((void*)0));
547
548 return app;
549}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-1e2fd5.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-1e2fd5.html new file mode 100644 index 0000000..b8782fd --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-1e2fd5.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 439, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-2eed80.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-2eed80.html new file mode 100644 index 0000000..1d9ee84 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-2eed80.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 404, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-519bf9.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-519bf9.html new file mode 100644 index 0000000..53c1cf2 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-519bf9.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 409, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-5555d9.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-5555d9.html new file mode 100644 index 0000000..db88242 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-5555d9.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 458, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-87f973.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-87f973.html new file mode 100644 index 0000000..01af118 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-87f973.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 449, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-8d22c7.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-8d22c7.html new file mode 100644 index 0000000..5954663 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-8d22c7.html @@ -0,0 +1,901 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__((noinline)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500
501/* GObject stuff */
502static void
503maximus_app_class_init (MaximusAppClass *klass)
504{
505}
506
507static void
508maximus_app_init (MaximusApp *app)
509{
510 MaximusAppPrivate *priv;
511 WnckScreen *screen;
512
513 priv = app->priv = maximus_app_get_instance_private (app);
514
515 priv->bind = maximus_bind_get_default ();
516
517 was_decorated = g_quark_from_static_string ("was-decorated");
518
519 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
520
521 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
522 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
523 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
524 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
525 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
526 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
527
528 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
529 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
530 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
531 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
532
533 priv->screen = screen = wnck_screen_get_default ();
534 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
535 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
536}
537
538MaximusApp *
539maximus_app_get_default (void)
540
541{
542 static MaximusApp *app = NULL((void*)0);
543
544 if (!app)
545 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
546 NULL((void*)0));
547
548 return app;
549}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-a2ef3d.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-a2ef3d.html new file mode 100644 index 0000000..87b3b13 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-a2ef3d.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 414, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-b113da.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-b113da.html new file mode 100644 index 0000000..f4bc22a --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-b113da.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 419, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-bc0f47.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-bc0f47.html new file mode 100644 index 0000000..a90bbd2 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-bc0f47.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 424, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-cf4342.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-cf4342.html new file mode 100644 index 0000000..90f9e8a --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-cf4342.html @@ -0,0 +1,849 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 467, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c maximus-bind.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__((noinline)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281
282static void
283on_binding_activated (gchar *keystring, MaximusBind *bind)
284{
285 MaximusBindPrivate *priv;
286 WnckWindow *active;
287
288 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
289 priv = bind->priv;
290
291 active = wnck_screen_get_active_window (priv->screen);
292
293 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
294 return;
295
296 if (wnck_window_is_fullscreen (active))
297 {
298 unfullscreen (bind, active);
299 }
300 else
301 {
302 fullscreen (bind, active);
303 }
304}
305
306/* Callbacks */
307static gboolean
308binding_is_valid (const gchar *binding)
309{
310 gboolean retval = TRUE(!(0));
311
312 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
313 retval = FALSE(0);
314
315 return retval;
316}
317
318static void
319on_binding_changed (GSettings *settings,
320 gchar *key,
321 MaximusBind *bind)
322{
323 MaximusBindPrivate *priv;
324
325 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
326 priv = bind->priv;
327
328 if (binding_is_valid (priv->binding))
329 tomboy_keybinder_unbind (priv->binding,
330 (TomboyBindkeyHandler)on_binding_changed);
331 g_free (priv->binding);
332
333 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
334
335 if (binding_is_valid (priv->binding))
336 tomboy_keybinder_bind (priv->binding,
337 (TomboyBindkeyHandler)on_binding_activated,
338 bind);
339
340 g_print ("Binding changed: %s\n", priv->binding);
341}
342
343
344/* GObject stuff */
345static void
346create_rule (MaximusBind *bind, const gchar *filename)
347{
348#define RULE_GROUP"Fullscreening" "Fullscreening"
349#define RULE_WMCLASS"WMClass" "WMClass"
350#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
351#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
352 MaximusBindPrivate *priv;
353 GKeyFile *file;
354 GError *error = NULL((void*)0);
355 MaximusRule *rule;
356
357 priv = bind->priv;
358
359 file = g_key_file_new ();
360 g_key_file_load_from_file (file, filename, 0, &error);
361 if (error)
362 {
363 g_warning ("Unable to load %s: %s\n", filename, error->message);
364 g_error_free (error);
365 g_key_file_free (file);
366 return;
367 }
368
369 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
370
371 rule->wm_class = g_key_file_get_string (file,
372 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
373 NULL((void*)0));
374 rule->fullscreen = g_key_file_get_string (file,
375 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
376 NULL((void*)0));
377 rule->unfullscreen = g_key_file_get_string (file,
378 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
379 NULL((void*)0));
380 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
381 {
382 g_free (rule->wm_class);
383 g_free (rule->fullscreen);
384 g_free (rule->unfullscreen);
385 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
386
387 g_warning ("Unable to load %s, missing strings", filename);
388 }
389 else
390 priv->rules = g_list_append (priv->rules, rule);
391
392 g_key_file_free (file);
393}
394
395static void
396load_rules (MaximusBind *bind, const gchar *path)
397{
398 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
399 GDir *dir;
400 const gchar *name;
401
402 priv = bind->priv;
403
404 dir = g_dir_open (path, 0, NULL((void*)0));
405
406 if (!dir)
407 return;
408
409 while ((name = g_dir_read_name (dir)))
410 {
411 gchar *filename;
412
413 filename= g_build_filename (path, name, NULL((void*)0));
414
415 create_rule (bind, filename);
416
417 g_free (filename);
418 }
419
420
421 g_dir_close (dir);
422}
423
424static void
425maximus_bind_finalize (GObject *obj)
426{
427 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) g_type_check_instance_cast ((GTypeInstance*
) ((obj)), ((maximus_bind_get_type ()))))))
;
428 MaximusBindPrivate *priv;
429 GList *r;
430
431 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
432 priv = bind->priv;
433
434 for (r = priv->rules; r; r = r->next)
435 {
436 MaximusRule *rule = r->data;
437
438 g_free (rule->wm_class);
439 g_free (rule->fullscreen);
440 g_free (rule->unfullscreen);
441
442 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
443 }
444 g_free (priv->binding);
445
446 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((maximus_bind_parent_class
)), (((GType) ((20) << (2))))))))
->finalize (obj);
447}
448
449static void
450maximus_bind_class_init (MaximusBindClass *klass)
451{
452 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass
)), (((GType) ((20) << (2))))))))
;
453
454 obj_class->finalize = maximus_bind_finalize;
455}
456
457static void
458maximus_bind_init (MaximusBind *bind)
459{
460 MaximusBindPrivate *priv;
461 GdkDisplay *display = gdk_display_get_default ();
462 WnckScreen *screen;
463
464 priv = bind->priv = maximus_bind_get_instance_private (bind);
465
466 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
467 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
468 priv->rules = NULL((void*)0);
469 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
470
471 tomboy_keybinder_init ();
472
473 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
474 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
475
476 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
477
478 if (binding_is_valid (priv->binding))
479 tomboy_keybinder_bind (priv->binding,
480 (TomboyBindkeyHandler)on_binding_activated,
481 bind);
482
483 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
484}
485
486MaximusBind *
487maximus_bind_get_default (void)
488
489{
490 static MaximusBind *bind = NULL((void*)0);
491
492 if (!bind)
493 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
494 NULL((void*)0));
495
496 return bind;
497}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-d86ec3.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-d86ec3.html new file mode 100644 index 0000000..8caaa4d --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-d86ec3.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 444, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-f8083f.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-f8083f.html new file mode 100644 index 0000000..eb38dc5 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-f8083f.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 434, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-06-21-213305-5323-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/scanview.css b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/sorttable.js b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+
+ + + diff --git a/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/1.html b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/1.html new file mode 100644 index 0000000..854a5f6 --- /dev/null +++ b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/1.html @@ -0,0 +1,379 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+
+ + + diff --git a/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/2.html b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/2.html new file mode 100644 index 0000000..3945a93 --- /dev/null +++ b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/2.html @@ -0,0 +1,1273 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;<--- Assuming that condition '!data' is not redundant
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+
+ + + diff --git a/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/3.html b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/3.html new file mode 100644 index 0000000..8cf3f42 --- /dev/null +++ b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/3.html @@ -0,0 +1,1169 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+
+ + + diff --git a/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/index.html b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/index.html new file mode 100644 index 0000000..84df1b3 --- /dev/null +++ b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/index.html @@ -0,0 +1,129 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
0missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
402unreadVariable563styleVariable 'priv' is assigned a value that is never used.
+
+
+ + + diff --git a/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/stats.html b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/stats.html new file mode 100644 index 0000000..36cad0c --- /dev/null +++ b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/stats.html @@ -0,0 +1,108 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+

Top 10 files for style severity, total findings: 8
+   5  maximus/maximus-bind.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+
+ + + diff --git a/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/style.css b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/style.css new file mode 100644 index 0000000..07125f4 --- /dev/null +++ b/2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/style.css @@ -0,0 +1,137 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + margin: 0; + width: auto; +} + +h1 { + margin: 10px; +} + +.header { + border-bottom: thin solid #aaa; +} + +.footer { + border-top: thin solid #aaa; + font-size: 90%; + margin-top: 5px; +} + +.footer ul { + list-style-type: none; + padding-left: 0; +} + +.footer > p { + margin: 4px; +} + +.wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +#menu, +#menu_index { + text-align: left; + width: 350px; + height: 90vh; + min-height: 200px; + overflow: auto; + position: -webkit-sticky; + position: sticky; + top: 0; + padding: 0 15px 15px 15px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +#content, +#content_index { + background-color: #fff; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding: 0 15px 15px 15px; + width: calc(100% - 350px); + height: 100%; + overflow-x: auto; +} + +#filename { + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + z-index: 10; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.d-none { + display: none; +} diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/index.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/index.html new file mode 100644 index 0000000..b2bf0ee --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@6103b827c801
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 12.0.0 (Fedora 12.0.0-2.fc34) +
Date:Sat Aug 7 12:36:20 2021
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Dead store
Dead nested assignment1
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Dead storeDead nested assignmentmaximus-bind.cmaximus_bind_init4671View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4241View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4541View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4341View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4491View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4041View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4441View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4581View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4141View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4391View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4291View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4191View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4091View Report
+ + diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-0af285.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-0af285.html new file mode 100644 index 0000000..efe43f4 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-0af285.html @@ -0,0 +1,901 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__((noinline)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500
501/* GObject stuff */
502static void
503maximus_app_class_init (MaximusAppClass *klass)
504{
505}
506
507static void
508maximus_app_init (MaximusApp *app)
509{
510 MaximusAppPrivate *priv;
511 WnckScreen *screen;
512
513 priv = app->priv = maximus_app_get_instance_private (app);
514
515 priv->bind = maximus_bind_get_default ();
516
517 was_decorated = g_quark_from_static_string ("was-decorated");
518
519 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
520
521 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
522 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
523 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
524 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
525 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
526 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
527
528 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
529 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
530 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
531 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
532
533 priv->screen = screen = wnck_screen_get_default ();
534 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
535 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
536}
537
538MaximusApp *
539maximus_app_get_default (void)
540
541{
542 static MaximusApp *app = NULL((void*)0);
543
544 if (!app)
545 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
546 NULL((void*)0));
547
548 return app;
549}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-12d4c1.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-12d4c1.html new file mode 100644 index 0000000..056e627 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-12d4c1.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 424, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-35a7be.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-35a7be.html new file mode 100644 index 0000000..1026cf3 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-35a7be.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 454, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-436dd6.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-436dd6.html new file mode 100644 index 0000000..787f16b --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-436dd6.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 434, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-44b187.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-44b187.html new file mode 100644 index 0000000..677e0d9 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-44b187.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 449, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-6392ce.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-6392ce.html new file mode 100644 index 0000000..e6b2c56 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-6392ce.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 404, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-771039.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-771039.html new file mode 100644 index 0000000..9d4cd0e --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-771039.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 444, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-8f2ecf.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-8f2ecf.html new file mode 100644 index 0000000..3b90bc4 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-8f2ecf.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 458, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-9fb331.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-9fb331.html new file mode 100644 index 0000000..bda3142 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-9fb331.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 414, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a656a8.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a656a8.html new file mode 100644 index 0000000..4a02b3c --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a656a8.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 439, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a9552c.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a9552c.html new file mode 100644 index 0000000..ebcaea1 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a9552c.html @@ -0,0 +1,901 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__((noinline)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500
501/* GObject stuff */
502static void
503maximus_app_class_init (MaximusAppClass *klass)
504{
505}
506
507static void
508maximus_app_init (MaximusApp *app)
509{
510 MaximusAppPrivate *priv;
511 WnckScreen *screen;
512
513 priv = app->priv = maximus_app_get_instance_private (app);
514
515 priv->bind = maximus_bind_get_default ();
516
517 was_decorated = g_quark_from_static_string ("was-decorated");
518
519 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
520
521 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
522 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
523 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
524 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
525 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
526 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
527
528 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
529 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
530 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
531 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
532
533 priv->screen = screen = wnck_screen_get_default ();
534 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
535 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
536}
537
538MaximusApp *
539maximus_app_get_default (void)
540
541{
542 static MaximusApp *app = NULL((void*)0);
543
544 if (!app)
545 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
546 NULL((void*)0));
547
548 return app;
549}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c24641.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c24641.html new file mode 100644 index 0000000..703e4be --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c24641.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 429, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c9832e.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c9832e.html new file mode 100644 index 0000000..2c97cca --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c9832e.html @@ -0,0 +1,849 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 467, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c maximus-bind.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__((noinline)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281
282static void
283on_binding_activated (gchar *keystring, MaximusBind *bind)
284{
285 MaximusBindPrivate *priv;
286 WnckWindow *active;
287
288 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
289 priv = bind->priv;
290
291 active = wnck_screen_get_active_window (priv->screen);
292
293 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
294 return;
295
296 if (wnck_window_is_fullscreen (active))
297 {
298 unfullscreen (bind, active);
299 }
300 else
301 {
302 fullscreen (bind, active);
303 }
304}
305
306/* Callbacks */
307static gboolean
308binding_is_valid (const gchar *binding)
309{
310 gboolean retval = TRUE(!(0));
311
312 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
313 retval = FALSE(0);
314
315 return retval;
316}
317
318static void
319on_binding_changed (GSettings *settings,
320 gchar *key,
321 MaximusBind *bind)
322{
323 MaximusBindPrivate *priv;
324
325 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
326 priv = bind->priv;
327
328 if (binding_is_valid (priv->binding))
329 tomboy_keybinder_unbind (priv->binding,
330 (TomboyBindkeyHandler)on_binding_changed);
331 g_free (priv->binding);
332
333 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
334
335 if (binding_is_valid (priv->binding))
336 tomboy_keybinder_bind (priv->binding,
337 (TomboyBindkeyHandler)on_binding_activated,
338 bind);
339
340 g_print ("Binding changed: %s\n", priv->binding);
341}
342
343
344/* GObject stuff */
345static void
346create_rule (MaximusBind *bind, const gchar *filename)
347{
348#define RULE_GROUP"Fullscreening" "Fullscreening"
349#define RULE_WMCLASS"WMClass" "WMClass"
350#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
351#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
352 MaximusBindPrivate *priv;
353 GKeyFile *file;
354 GError *error = NULL((void*)0);
355 MaximusRule *rule;
356
357 priv = bind->priv;
358
359 file = g_key_file_new ();
360 g_key_file_load_from_file (file, filename, 0, &error);
361 if (error)
362 {
363 g_warning ("Unable to load %s: %s\n", filename, error->message);
364 g_error_free (error);
365 g_key_file_free (file);
366 return;
367 }
368
369 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
370
371 rule->wm_class = g_key_file_get_string (file,
372 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
373 NULL((void*)0));
374 rule->fullscreen = g_key_file_get_string (file,
375 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
376 NULL((void*)0));
377 rule->unfullscreen = g_key_file_get_string (file,
378 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
379 NULL((void*)0));
380 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
381 {
382 g_free (rule->wm_class);
383 g_free (rule->fullscreen);
384 g_free (rule->unfullscreen);
385 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
386
387 g_warning ("Unable to load %s, missing strings", filename);
388 }
389 else
390 priv->rules = g_list_append (priv->rules, rule);
391
392 g_key_file_free (file);
393}
394
395static void
396load_rules (MaximusBind *bind, const gchar *path)
397{
398 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
399 GDir *dir;
400 const gchar *name;
401
402 priv = bind->priv;
403
404 dir = g_dir_open (path, 0, NULL((void*)0));
405
406 if (!dir)
407 return;
408
409 while ((name = g_dir_read_name (dir)))
410 {
411 gchar *filename;
412
413 filename= g_build_filename (path, name, NULL((void*)0));
414
415 create_rule (bind, filename);
416
417 g_free (filename);
418 }
419
420
421 g_dir_close (dir);
422}
423
424static void
425maximus_bind_finalize (GObject *obj)
426{
427 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) g_type_check_instance_cast ((GTypeInstance*
) ((obj)), ((maximus_bind_get_type ()))))))
;
428 MaximusBindPrivate *priv;
429 GList *r;
430
431 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
432 priv = bind->priv;
433
434 for (r = priv->rules; r; r = r->next)
435 {
436 MaximusRule *rule = r->data;
437
438 g_free (rule->wm_class);
439 g_free (rule->fullscreen);
440 g_free (rule->unfullscreen);
441
442 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
443 }
444 g_free (priv->binding);
445
446 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((maximus_bind_parent_class
)), (((GType) ((20) << (2))))))))
->finalize (obj);
447}
448
449static void
450maximus_bind_class_init (MaximusBindClass *klass)
451{
452 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass
)), (((GType) ((20) << (2))))))))
;
453
454 obj_class->finalize = maximus_bind_finalize;
455}
456
457static void
458maximus_bind_init (MaximusBind *bind)
459{
460 MaximusBindPrivate *priv;
461 GdkDisplay *display = gdk_display_get_default ();
462 WnckScreen *screen;
463
464 priv = bind->priv = maximus_bind_get_instance_private (bind);
465
466 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
467 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
468 priv->rules = NULL((void*)0);
469 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
470
471 tomboy_keybinder_init ();
472
473 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
474 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
475
476 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
477
478 if (binding_is_valid (priv->binding))
479 tomboy_keybinder_bind (priv->binding,
480 (TomboyBindkeyHandler)on_binding_activated,
481 bind);
482
483 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
484}
485
486MaximusBind *
487maximus_bind_get_default (void)
488
489{
490 static MaximusBind *bind = NULL((void*)0);
491
492 if (!bind)
493 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
494 NULL((void*)0));
495
496 return bind;
497}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-d99c84.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-d99c84.html new file mode 100644 index 0000000..b7c4f32 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-d99c84.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 419, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-f5890d.html b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-f5890d.html new file mode 100644 index 0000000..494357f --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-f5890d.html @@ -0,0 +1,1009 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 409, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir /rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -o /rootdir/html-report/2021-08-07-123620-5316-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334
335/**
336 * egg_virtual_accelerator_name:
337 * @accelerator_key: accelerator keyval
338 * @accelerator_mods: accelerator modifier mask
339 * @returns: a newly-allocated accelerator name
340 *
341 * Converts an accelerator keyval and modifier mask
342 * into a string parseable by egg_accelerator_parse_virtual().
343 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
344 * this function returns "&lt;Control&gt;q".
345 *
346 * The caller of this function must free the returned string.
347 */
348gchar*
349egg_virtual_accelerator_name (guint accelerator_key,
350 EggVirtualModifierType accelerator_mods)
351{
352 static const gchar text_release[] = "<Release>";
353 static const gchar text_shift[] = "<Shift>";
354 static const gchar text_control[] = "<Control>";
355 static const gchar text_mod1[] = "<Alt>";
356 static const gchar text_mod2[] = "<Mod2>";
357 static const gchar text_mod3[] = "<Mod3>";
358 static const gchar text_mod4[] = "<Mod4>";
359 static const gchar text_mod5[] = "<Mod5>";
360 static const gchar text_meta[] = "<Meta>";
361 static const gchar text_super[] = "<Super>";
362 static const gchar text_hyper[] = "<Hyper>";
363 guint l;
364 gchar *keyval_name;
365 gchar *accelerator;
366
367 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
368
369 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
370 if (!keyval_name)
371 keyval_name = "";
372
373 l = 0;
374 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
375 l += sizeof (text_release) - 1;
376 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
377 l += sizeof (text_shift) - 1;
378 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
379 l += sizeof (text_control) - 1;
380 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
381 l += sizeof (text_mod1) - 1;
382 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
383 l += sizeof (text_mod2) - 1;
384 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
385 l += sizeof (text_mod3) - 1;
386 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
387 l += sizeof (text_mod4) - 1;
388 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
389 l += sizeof (text_mod5) - 1;
390 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
391 l += sizeof (text_meta) - 1;
392 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
393 l += sizeof (text_hyper) - 1;
394 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
395 l += sizeof (text_super) - 1;
396 l += strlen (keyval_name);
397
398 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
399
400 l = 0;
401 accelerator[l] = 0;
402 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
403 {
404 strcpy (accelerator + l, text_release);
405 l += sizeof (text_release) - 1;
406 }
407 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
408 {
409 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
410 l += sizeof (text_shift) - 1;
411 }
412 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
413 {
414 strcpy (accelerator + l, text_control);
415 l += sizeof (text_control) - 1;
416 }
417 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
418 {
419 strcpy (accelerator + l, text_mod1);
420 l += sizeof (text_mod1) - 1;
421 }
422 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
423 {
424 strcpy (accelerator + l, text_mod2);
425 l += sizeof (text_mod2) - 1;
426 }
427 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
428 {
429 strcpy (accelerator + l, text_mod3);
430 l += sizeof (text_mod3) - 1;
431 }
432 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
433 {
434 strcpy (accelerator + l, text_mod4);
435 l += sizeof (text_mod4) - 1;
436 }
437 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
438 {
439 strcpy (accelerator + l, text_mod5);
440 l += sizeof (text_mod5) - 1;
441 }
442 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
443 {
444 strcpy (accelerator + l, text_meta);
445 l += sizeof (text_meta) - 1;
446 }
447 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
448 {
449 strcpy (accelerator + l, text_hyper);
450 l += sizeof (text_hyper) - 1;
451 }
452 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
453 {
454 strcpy (accelerator + l, text_super);
455 l += sizeof (text_super) - 1;
456 }
457
458 strcpy (accelerator + l, keyval_name);
459
460 return accelerator;
461}
462
463void
464egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
465 EggVirtualModifierType virtual_mods,
466 GdkModifierType *concrete_mods)
467{
468 GdkModifierType concrete;
469 int i;
470 const EggModmap *modmap;
471
472 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
473 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
474
475 modmap = egg_keymap_get_modmap (keymap);
476
477 /* Not so sure about this algorithm. */
478
479 concrete = 0;
480 i = 0;
481 while (i < EGG_MODMAP_ENTRY_LAST)
482 {
483 if (modmap->mapping[i] & virtual_mods)
484 concrete |= (1 << i);
485
486 ++i;
487 }
488
489 *concrete_mods = concrete;
490}
491
492void
493egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
494 GdkModifierType concrete_mods,
495 EggVirtualModifierType *virtual_mods)
496{
497 GdkModifierType virtual;
498 int i;
499 const EggModmap *modmap;
500
501 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
502 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
503
504 modmap = egg_keymap_get_modmap (keymap);
505
506 /* Not so sure about this algorithm. */
507
508 virtual = 0;
509 i = 0;
510 while (i < EGG_MODMAP_ENTRY_LAST)
511 {
512 if ((1 << i) & concrete_mods)
513 {
514 EggVirtualModifierType cleaned;
515
516 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
517 EGG_VIRTUAL_MOD3_MASK |
518 EGG_VIRTUAL_MOD4_MASK |
519 EGG_VIRTUAL_MOD5_MASK);
520
521 if (cleaned != 0)
522 {
523 virtual |= cleaned;
524 }
525 else
526 {
527 /* Rather than dropping mod2->mod5 if not bound,
528 * go ahead and use the concrete names
529 */
530 virtual |= modmap->mapping[i];
531 }
532 }
533
534 ++i;
535 }
536
537 *virtual_mods = virtual;
538}
539
540static void
541reload_modmap (GdkKeymap *keymap,
542 EggModmap *modmap)
543{
544 XModifierKeymap *xmodmap;
545 int map_size;
546 int i;
547
548 /* FIXME multihead */
549 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
550
551 memset (modmap->mapping, 0, sizeof (modmap->mapping));
552
553 /* there are 8 modifiers, and the first 3 are shift, shift lock,
554 * and control
555 */
556 map_size = 8 * xmodmap->max_keypermod;
557 i = 3 * xmodmap->max_keypermod;
558 while (i < map_size)
559 {
560 /* get the key code at this point in the map,
561 * see if its keysym is one we're interested in
562 */
563 int keycode = xmodmap->modifiermap[i];
564 GdkKeymapKey *keys;
565 guint *keyvals;
566 int n_entries;
567 int j;
568 EggVirtualModifierType mask;
569
570 keys = NULL((void*)0);
571 keyvals = NULL((void*)0);
572 n_entries = 0;
573
574 gdk_keymap_get_entries_for_keycode (keymap,
575 keycode,
576 &keys, &keyvals, &n_entries);
577
578 mask = 0;
579 j = 0;
580 while (j < n_entries)
581 {
582 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
583 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
584 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
585 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
586 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
587 keyvals[j] == GDK_KEY_Meta_R0xffe8)
588 mask |= EGG_VIRTUAL_META_MASK;
589 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
590 keyvals[j] == GDK_KEY_Hyper_R0xffee)
591 mask |= EGG_VIRTUAL_HYPER_MASK;
592 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
593 keyvals[j] == GDK_KEY_Super_R0xffec)
594 mask |= EGG_VIRTUAL_SUPER_MASK;
595 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
596 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
597
598 ++j;
599 }
600
601 /* Mod1Mask is 1 << 3 for example, i.e. the
602 * fourth modifier, i / keyspermod is the modifier
603 * index
604 */
605 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
606
607 g_free (keyvals);
608 g_free (keys);
609
610 ++i;
611 }
612
613 /* Add in the not-really-virtual fixed entries */
614 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
621 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
622
623 XFreeModifiermap (xmodmap);
624}
625
626const EggModmap*
627egg_keymap_get_modmap (GdkKeymap *keymap)
628{
629 EggModmap *modmap;
630
631 /* This is all a hack, much simpler when we can just
632 * modify GDK directly.
633 */
634
635 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
636 "egg-modmap");
637
638 if (modmap == NULL((void*)0))
639 {
640 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
641
642 /* FIXME modify keymap change events with an event filter
643 * and force a reload if we get one
644 */
645
646 reload_modmap (keymap, modmap);
647
648 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
649 "egg-modmap",
650 modmap,
651 g_free);
652 }
653
654 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
655
656 return modmap;
657}
diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/scanview.css b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/sorttable.js b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+
+ + + diff --git a/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/1.html b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/1.html new file mode 100644 index 0000000..194dd1e --- /dev/null +++ b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/1.html @@ -0,0 +1,379 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+
+ + + diff --git a/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/2.html b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/2.html new file mode 100644 index 0000000..adcefd0 --- /dev/null +++ b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/2.html @@ -0,0 +1,1273 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;<--- Assuming that condition '!data' is not redundant
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+
+ + + diff --git a/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/3.html b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/3.html new file mode 100644 index 0000000..94d5e53 --- /dev/null +++ b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/3.html @@ -0,0 +1,1169 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+
+ + + diff --git a/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/index.html b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/index.html new file mode 100644 index 0000000..5e2259e --- /dev/null +++ b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/index.html @@ -0,0 +1,129 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
0missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
402unreadVariable563styleVariable 'priv' is assigned a value that is never used.
+
+
+ + + diff --git a/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/stats.html b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/stats.html new file mode 100644 index 0000000..cd27bcd --- /dev/null +++ b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/stats.html @@ -0,0 +1,108 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+

Top 10 files for style severity, total findings: 8
+   5  maximus/maximus-bind.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+
+ + + diff --git a/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/style.css b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/style.css new file mode 100644 index 0000000..07125f4 --- /dev/null +++ b/2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/style.css @@ -0,0 +1,137 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + margin: 0; + width: auto; +} + +h1 { + margin: 10px; +} + +.header { + border-bottom: thin solid #aaa; +} + +.footer { + border-top: thin solid #aaa; + font-size: 90%; + margin-top: 5px; +} + +.footer ul { + list-style-type: none; + padding-left: 0; +} + +.footer > p { + margin: 4px; +} + +.wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +#menu, +#menu_index { + text-align: left; + width: 350px; + height: 90vh; + min-height: 200px; + overflow: auto; + position: -webkit-sticky; + position: sticky; + top: 0; + padding: 0 15px 15px 15px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +#content, +#content_index { + background-color: #fff; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding: 0 15px 15px 15px; + width: calc(100% - 350px); + height: 100%; + overflow-x: auto; +} + +#filename { + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + z-index: 10; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.d-none { + display: none; +} diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/index.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/index.html new file mode 100644 index 0000000..812b9a6 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@bae79f5555d3
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 13.0.0 (Fedora 13.0.0-3.fc35) +
Date:Sat Dec 11 15:06:38 2021
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
+ + diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-2e5333.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-2e5333.html new file mode 100644 index 0000000..65264e0 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-2e5333.html @@ -0,0 +1,900 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-326845.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-326845.html new file mode 100644 index 0000000..10191b8 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-326845.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-336491.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-336491.html new file mode 100644 index 0000000..c83cd28 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-336491.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-372a66.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-372a66.html new file mode 100644 index 0000000..1e41a06 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-372a66.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-51b5f0.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-51b5f0.html new file mode 100644 index 0000000..df8ff99 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-51b5f0.html @@ -0,0 +1,900 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-522919.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-522919.html new file mode 100644 index 0000000..07749ad --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-522919.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-5c876e.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-5c876e.html new file mode 100644 index 0000000..62709a0 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-5c876e.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-85e0db.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-85e0db.html new file mode 100644 index 0000000..32c7448 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-85e0db.html @@ -0,0 +1,846 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c maximus-bind.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) g_type_check_instance_cast ((GTypeInstance*
) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((maximus_bind_parent_class
)), (((GType) ((20) << (2))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass
)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-8d8a6a.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-8d8a6a.html new file mode 100644 index 0000000..672c830 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-8d8a6a.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-a7affc.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-a7affc.html new file mode 100644 index 0000000..b28098e --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-a7affc.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c01286.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c01286.html new file mode 100644 index 0000000..b869f2a --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c01286.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c17e44.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c17e44.html new file mode 100644 index 0000000..f0a1fe8 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c17e44.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-cc16b0.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-cc16b0.html new file mode 100644 index 0000000..ce7da28 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-cc16b0.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e2a874.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e2a874.html new file mode 100644 index 0000000..bbb835a --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e2a874.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e488cf.html b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e488cf.html new file mode 100644 index 0000000..8e0cb7e --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e488cf.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2021-12-11-150638-5462-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/scanview.css b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2021-12-11-150638-5462-1@d1ffecd40bf5_master/sorttable.js b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2021-12-11-150638-5462-1@d1ffecd40bf5_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/1.html b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/1.html new file mode 100644 index 0000000..e6eb3fc --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/1.html @@ -0,0 +1,379 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/2.html b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/2.html new file mode 100644 index 0000000..de08493 --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/2.html @@ -0,0 +1,1271 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;<--- Assuming that condition '!data' is not redundant
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/3.html b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/3.html new file mode 100644 index 0000000..73ef27e --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/3.html @@ -0,0 +1,1163 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/4.html b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/4.html new file mode 100644 index 0000000..75deb6d --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/4.html @@ -0,0 +1,853 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/index.html b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/index.html new file mode 100644 index 0000000..bb77dd3 --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/index.html @@ -0,0 +1,132 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/stats.html b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/stats.html new file mode 100644 index 0000000..2528133 --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/stats.html @@ -0,0 +1,109 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+
+ + + diff --git a/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/style.css b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/style.css new file mode 100644 index 0000000..07125f4 --- /dev/null +++ b/2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/style.css @@ -0,0 +1,137 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + margin: 0; + width: auto; +} + +h1 { + margin: 10px; +} + +.header { + border-bottom: thin solid #aaa; +} + +.footer { + border-top: thin solid #aaa; + font-size: 90%; + margin-top: 5px; +} + +.footer ul { + list-style-type: none; + padding-left: 0; +} + +.footer > p { + margin: 4px; +} + +.wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +#menu, +#menu_index { + text-align: left; + width: 350px; + height: 90vh; + min-height: 200px; + overflow: auto; + position: -webkit-sticky; + position: sticky; + top: 0; + padding: 0 15px 15px 15px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +#content, +#content_index { + background-color: #fff; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding: 0 15px 15px 15px; + width: calc(100% - 350px); + height: 100%; + overflow-x: auto; +} + +#filename { + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + z-index: 10; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.d-none { + display: none; +} diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/index.html b/2022-02-13-183617-5516-1@becf3036fb90_master/index.html new file mode 100644 index 0000000..733114f --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@1c4ea89342a8
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 13.0.0 (Fedora 13.0.0-3.fc35) +
Date:Sun Feb 13 18:36:17 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
+ + diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html new file mode 100644 index 0000000..77bce5a --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html new file mode 100644 index 0000000..bf6b563 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html new file mode 100644 index 0000000..2f4637c --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html new file mode 100644 index 0000000..244f063 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html @@ -0,0 +1,900 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html new file mode 100644 index 0000000..e9853bf --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html new file mode 100644 index 0000000..915385e --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html @@ -0,0 +1,900 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html new file mode 100644 index 0000000..56f8a34 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html new file mode 100644 index 0000000..67975b2 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html new file mode 100644 index 0000000..be4b690 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html new file mode 100644 index 0000000..7dc0eb8 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html new file mode 100644 index 0000000..b21c8b0 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html @@ -0,0 +1,846 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c maximus-bind.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) g_type_check_instance_cast ((GTypeInstance*
) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((maximus_bind_parent_class
)), (((GType) ((20) << (2))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass
)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html new file mode 100644 index 0000000..12fcf09 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html new file mode 100644 index 0000000..d412c57 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html new file mode 100644 index 0000000..88bbd49 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html new file mode 100644 index 0000000..e10ce15 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css b/2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js b/2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/1.html b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/1.html new file mode 100644 index 0000000..e6eb3fc --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/1.html @@ -0,0 +1,379 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/2.html b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/2.html new file mode 100644 index 0000000..de08493 --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/2.html @@ -0,0 +1,1271 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;<--- Assuming that condition '!data' is not redundant
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/3.html b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/3.html new file mode 100644 index 0000000..73ef27e --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/3.html @@ -0,0 +1,1163 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/4.html b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/4.html new file mode 100644 index 0000000..75deb6d --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/4.html @@ -0,0 +1,853 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/index.html b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/index.html new file mode 100644 index 0000000..bb77dd3 --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/index.html @@ -0,0 +1,132 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/stats.html b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/stats.html new file mode 100644 index 0000000..2528133 --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/stats.html @@ -0,0 +1,109 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + + +
+ +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+
+ + + diff --git a/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/style.css b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/style.css new file mode 100644 index 0000000..07125f4 --- /dev/null +++ b/2022-02-13-183640-2877-cppcheck@becf3036fb90_master/style.css @@ -0,0 +1,137 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + margin: 0; + width: auto; +} + +h1 { + margin: 10px; +} + +.header { + border-bottom: thin solid #aaa; +} + +.footer { + border-top: thin solid #aaa; + font-size: 90%; + margin-top: 5px; +} + +.footer ul { + list-style-type: none; + padding-left: 0; +} + +.footer > p { + margin: 4px; +} + +.wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +#menu, +#menu_index { + text-align: left; + width: 350px; + height: 90vh; + min-height: 200px; + overflow: auto; + position: -webkit-sticky; + position: sticky; + top: 0; + padding: 0 15px 15px 15px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +#content, +#content_index { + background-color: #fff; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding: 0 15px 15px 15px; + width: calc(100% - 350px); + height: 100%; + overflow-x: auto; +} + +#filename { + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + z-index: 10; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.d-none { + display: none; +} diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/index.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/index.html new file mode 100644 index 0000000..03f1d28 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@fb484686ec9b
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 14.0.0 (Fedora 14.0.0-1.fc36) +
Date:Wed Jun 1 14:30:57 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
+ + diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-05d832.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-05d832.html new file mode 100644 index 0000000..27256d8 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-05d832.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-1f618a.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-1f618a.html new file mode 100644 index 0000000..1abffd0 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-1f618a.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-37b917.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-37b917.html new file mode 100644 index 0000000..9495853 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-37b917.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-4bda9e.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-4bda9e.html new file mode 100644 index 0000000..6cb257a --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-4bda9e.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-678a90.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-678a90.html new file mode 100644 index 0000000..425e933 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-678a90.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-6fb882.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-6fb882.html new file mode 100644 index 0000000..84eabc4 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-6fb882.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-7534c9.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-7534c9.html new file mode 100644 index 0000000..f235cff --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-7534c9.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-85a3e8.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-85a3e8.html new file mode 100644 index 0000000..349df89 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-85a3e8.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-90bf5a.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-90bf5a.html new file mode 100644 index 0000000..1915757 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-90bf5a.html @@ -0,0 +1,1174 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c maximus-bind.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((maximus_bind_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-aa2062.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-aa2062.html new file mode 100644 index 0000000..b5b0983 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-aa2062.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-b10f27.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-b10f27.html new file mode 100644 index 0000000..f43b37e --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-b10f27.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-c2cf20.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-c2cf20.html new file mode 100644 index 0000000..30b65d0 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-c2cf20.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e3bdb1.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e3bdb1.html new file mode 100644 index 0000000..4d7fdab --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e3bdb1.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e9ff85.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e9ff85.html new file mode 100644 index 0000000..5e4c9e9 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e9ff85.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-faab40.html b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-faab40.html new file mode 100644 index 0000000..45f2aef --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-faab40.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-06-01-143057-5441-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/scanview.css b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/sorttable.js b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/1.html b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/1.html new file mode 100644 index 0000000..8a1de11 --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/1.html @@ -0,0 +1,441 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/2.html b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/2.html new file mode 100644 index 0000000..b98bd46 --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/2.html @@ -0,0 +1,1333 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/3.html b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/3.html new file mode 100644 index 0000000..4ae4af0 --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/3.html @@ -0,0 +1,1225 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/4.html b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/4.html new file mode 100644 index 0000000..a0a1a2f --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/4.html @@ -0,0 +1,915 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/index.html b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/index.html new file mode 100644 index 0000000..b09bd8f --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/index.html @@ -0,0 +1,216 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/stats.html b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/stats.html new file mode 100644 index 0000000..5bd0965 --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/stats.html @@ -0,0 +1,171 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+ +
+ + diff --git a/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/style.css b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/index.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/index.html new file mode 100644 index 0000000..f05058f --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@2a336a96dfdf
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 14.0.5 (Fedora 14.0.5-1.fc36) +
Date:Fri Oct 28 21:31:07 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
+ + diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-05d832.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-05d832.html new file mode 100644 index 0000000..ffc6cc9 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-05d832.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-1f618a.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-1f618a.html new file mode 100644 index 0000000..b0179ce --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-1f618a.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-37b917.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-37b917.html new file mode 100644 index 0000000..0b83233 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-37b917.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-4bda9e.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-4bda9e.html new file mode 100644 index 0000000..2ced0a8 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-4bda9e.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-678a90.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-678a90.html new file mode 100644 index 0000000..7533f97 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-678a90.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-6fb882.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-6fb882.html new file mode 100644 index 0000000..33f78ba --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-6fb882.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-7534c9.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-7534c9.html new file mode 100644 index 0000000..4b91dfd --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-7534c9.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-85a3e8.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-85a3e8.html new file mode 100644 index 0000000..5b08956 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-85a3e8.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-90bf5a.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-90bf5a.html new file mode 100644 index 0000000..8db388b --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-90bf5a.html @@ -0,0 +1,1174 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c maximus-bind.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((maximus_bind_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-aa2062.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-aa2062.html new file mode 100644 index 0000000..17c7518 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-aa2062.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-b10f27.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-b10f27.html new file mode 100644 index 0000000..60ab8a0 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-b10f27.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-c2cf20.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-c2cf20.html new file mode 100644 index 0000000..483fd5e --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-c2cf20.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-e3bdb1.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-e3bdb1.html new file mode 100644 index 0000000..f0d2b8a --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-e3bdb1.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-e9ff85.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-e9ff85.html new file mode 100644 index 0000000..6350337 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-e9ff85.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/report-faab40.html b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-faab40.html new file mode 100644 index 0000000..2d55b76 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/report-faab40.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-28-213107-5501-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/scanview.css b/2022-10-28-213107-5501-1@85b52143f8c1_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-10-28-213107-5501-1@85b52143f8c1_master/sorttable.js b/2022-10-28-213107-5501-1@85b52143f8c1_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-10-28-213107-5501-1@85b52143f8c1_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/1.html b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/1.html new file mode 100644 index 0000000..8a1de11 --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/1.html @@ -0,0 +1,441 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/2.html b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/2.html new file mode 100644 index 0000000..b98bd46 --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/2.html @@ -0,0 +1,1333 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/3.html b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/3.html new file mode 100644 index 0000000..4ae4af0 --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/3.html @@ -0,0 +1,1225 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/4.html b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/4.html new file mode 100644 index 0000000..a0a1a2f --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/4.html @@ -0,0 +1,915 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/index.html b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/index.html new file mode 100644 index 0000000..b09bd8f --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/index.html @@ -0,0 +1,216 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/stats.html b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/stats.html new file mode 100644 index 0000000..5bd0965 --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/stats.html @@ -0,0 +1,171 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+ +
+ + diff --git a/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/style.css b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/index.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/index.html new file mode 100644 index 0000000..321de6a --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@94ed60b4c71d
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 14.0.5 (Fedora 14.0.5-1.fc36) +
Date:Sat Oct 29 13:47:52 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
+ + diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-05d832.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-05d832.html new file mode 100644 index 0000000..685d182 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-05d832.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-1f618a.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-1f618a.html new file mode 100644 index 0000000..bdffb48 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-1f618a.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-37b917.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-37b917.html new file mode 100644 index 0000000..4d6bb25 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-37b917.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-4bda9e.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-4bda9e.html new file mode 100644 index 0000000..952b207 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-4bda9e.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-678a90.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-678a90.html new file mode 100644 index 0000000..40be66b --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-678a90.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-6fb882.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-6fb882.html new file mode 100644 index 0000000..abce720 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-6fb882.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-7534c9.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-7534c9.html new file mode 100644 index 0000000..9e3a502 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-7534c9.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-85a3e8.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-85a3e8.html new file mode 100644 index 0000000..8d5dc7e --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-85a3e8.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-90bf5a.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-90bf5a.html new file mode 100644 index 0000000..2b5fee8 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-90bf5a.html @@ -0,0 +1,1174 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c maximus-bind.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((maximus_bind_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-aa2062.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-aa2062.html new file mode 100644 index 0000000..339cb3a --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-aa2062.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-b10f27.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-b10f27.html new file mode 100644 index 0000000..18421ba --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-b10f27.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-c2cf20.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-c2cf20.html new file mode 100644 index 0000000..60ceb5a --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-c2cf20.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-e3bdb1.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-e3bdb1.html new file mode 100644 index 0000000..4d9f83a --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-e3bdb1.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-e9ff85.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-e9ff85.html new file mode 100644 index 0000000..2def2f8 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-e9ff85.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/report-faab40.html b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-faab40.html new file mode 100644 index 0000000..e4680a9 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/report-faab40.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-10-29-134752-5499-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/scanview.css b/2022-10-29-134752-5499-1@cd263b7986ec_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-10-29-134752-5499-1@cd263b7986ec_master/sorttable.js b/2022-10-29-134752-5499-1@cd263b7986ec_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-10-29-134752-5499-1@cd263b7986ec_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/1.html b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/1.html new file mode 100644 index 0000000..8a1de11 --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/1.html @@ -0,0 +1,441 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/2.html b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/2.html new file mode 100644 index 0000000..b98bd46 --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/2.html @@ -0,0 +1,1333 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/3.html b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/3.html new file mode 100644 index 0000000..4ae4af0 --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/3.html @@ -0,0 +1,1225 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/4.html b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/4.html new file mode 100644 index 0000000..a0a1a2f --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/4.html @@ -0,0 +1,915 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/index.html b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/index.html new file mode 100644 index 0000000..b09bd8f --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/index.html @@ -0,0 +1,216 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/stats.html b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/stats.html new file mode 100644 index 0000000..5bd0965 --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/stats.html @@ -0,0 +1,171 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+ +
+ + diff --git a/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/style.css b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/index.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/index.html new file mode 100644 index 0000000..daa7c59 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@725959c38f9a
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 14.0.5 (Fedora 14.0.5-1.fc36) +
Date:Fri Nov 11 18:03:10 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
+ + diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-05d832.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-05d832.html new file mode 100644 index 0000000..eea92b5 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-05d832.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-1f618a.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-1f618a.html new file mode 100644 index 0000000..2ccf437 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-1f618a.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-37b917.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-37b917.html new file mode 100644 index 0000000..cca5cfe --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-37b917.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-4bda9e.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-4bda9e.html new file mode 100644 index 0000000..71894bf --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-4bda9e.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-678a90.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-678a90.html new file mode 100644 index 0000000..3994edd --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-678a90.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-6fb882.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-6fb882.html new file mode 100644 index 0000000..4b4999d --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-6fb882.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-7534c9.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-7534c9.html new file mode 100644 index 0000000..f14e531 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-7534c9.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-85a3e8.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-85a3e8.html new file mode 100644 index 0000000..515a8d1 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-85a3e8.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-90bf5a.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-90bf5a.html new file mode 100644 index 0000000..c94e7b4 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-90bf5a.html @@ -0,0 +1,1174 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c maximus-bind.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((maximus_bind_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-aa2062.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-aa2062.html new file mode 100644 index 0000000..7f76d7c --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-aa2062.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-b10f27.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-b10f27.html new file mode 100644 index 0000000..a1be996 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-b10f27.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-c2cf20.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-c2cf20.html new file mode 100644 index 0000000..8fc08d5 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-c2cf20.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e3bdb1.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e3bdb1.html new file mode 100644 index 0000000..a37b55a --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e3bdb1.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e9ff85.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e9ff85.html new file mode 100644 index 0000000..409352e --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e9ff85.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-faab40.html b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-faab40.html new file mode 100644 index 0000000..b52da5c --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-faab40.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-180310-5358-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/scanview.css b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-11-11-180310-5358-1@6a7e6a9ee214_master/sorttable.js b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-11-11-180310-5358-1@6a7e6a9ee214_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/1.html b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/1.html new file mode 100644 index 0000000..8a1de11 --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/1.html @@ -0,0 +1,441 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/2.html b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/2.html new file mode 100644 index 0000000..b98bd46 --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/2.html @@ -0,0 +1,1333 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/3.html b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/3.html new file mode 100644 index 0000000..4ae4af0 --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/3.html @@ -0,0 +1,1225 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/4.html b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/4.html new file mode 100644 index 0000000..a0a1a2f --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/4.html @@ -0,0 +1,915 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/index.html b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/index.html new file mode 100644 index 0000000..b09bd8f --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/index.html @@ -0,0 +1,216 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/stats.html b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/stats.html new file mode 100644 index 0000000..5bd0965 --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/stats.html @@ -0,0 +1,171 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+ +
+ + diff --git a/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/style.css b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/index.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/index.html new file mode 100644 index 0000000..3ce8fe8 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@f44438d1008f
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 14.0.5 (Fedora 14.0.5-1.fc36) +
Date:Fri Nov 11 20:04:07 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
+ + diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-05d832.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-05d832.html new file mode 100644 index 0000000..558dae4 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-05d832.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-1f618a.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-1f618a.html new file mode 100644 index 0000000..fe25d81 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-1f618a.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-37b917.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-37b917.html new file mode 100644 index 0000000..bb5eb09 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-37b917.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-4bda9e.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-4bda9e.html new file mode 100644 index 0000000..07a03d3 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-4bda9e.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-678a90.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-678a90.html new file mode 100644 index 0000000..5508557 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-678a90.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-6fb882.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-6fb882.html new file mode 100644 index 0000000..b0461ca --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-6fb882.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-7534c9.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-7534c9.html new file mode 100644 index 0000000..e229d78 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-7534c9.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-85a3e8.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-85a3e8.html new file mode 100644 index 0000000..b07464a --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-85a3e8.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-90bf5a.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-90bf5a.html new file mode 100644 index 0000000..d0d9087 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-90bf5a.html @@ -0,0 +1,1174 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c maximus-bind.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((maximus_bind_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-aa2062.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-aa2062.html new file mode 100644 index 0000000..6f754a4 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-aa2062.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-b10f27.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-b10f27.html new file mode 100644 index 0000000..c0d80f6 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-b10f27.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-c2cf20.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-c2cf20.html new file mode 100644 index 0000000..db80720 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-c2cf20.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e3bdb1.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e3bdb1.html new file mode 100644 index 0000000..cf8942d --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e3bdb1.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e9ff85.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e9ff85.html new file mode 100644 index 0000000..85e408c --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e9ff85.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-faab40.html b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-faab40.html new file mode 100644 index 0000000..b542a8f --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-faab40.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/14.0.5 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/14.0.5/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-11-11-200407-5355-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/scanview.css b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/sorttable.js b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/1.html b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/1.html new file mode 100644 index 0000000..8a1de11 --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/1.html @@ -0,0 +1,441 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/2.html b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/2.html new file mode 100644 index 0000000..b98bd46 --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/2.html @@ -0,0 +1,1333 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/3.html b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/3.html new file mode 100644 index 0000000..4ae4af0 --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/3.html @@ -0,0 +1,1225 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/4.html b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/4.html new file mode 100644 index 0000000..a0a1a2f --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/4.html @@ -0,0 +1,915 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared with const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+
+
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/index.html b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/index.html new file mode 100644 index 0000000..b09bd8f --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/index.html @@ -0,0 +1,216 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
144unreadVariable563styleVariable 'display' is assigned a value that is never used.
203unreadVariable563styleVariable 'priv' is assigned a value that is never used.
218unreadVariable563styleVariable 'display' is assigned a value that is never used.
276unreadVariable563styleVariable 'priv' is assigned a value that is never used.
400unreadVariable563styleVariable 'priv' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared with const
+
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/stats.html b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/stats.html new file mode 100644 index 0000000..5bd0965 --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/stats.html @@ -0,0 +1,171 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+

Top 10 files for style severity, total findings: 9
+   5  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+ +
+ + diff --git a/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/style.css b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/index.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/index.html new file mode 100644 index 0000000..5028e68 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@d06d44a21b29
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 16.0.6 (Fedora 16.0.6-2.fc38) +
Date:Fri Jul 21 03:08:39 2023
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4671View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
+ + diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-05d832.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-05d832.html new file mode 100644 index 0000000..c31b204 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-05d832.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_22
; if (accelerator != ((void*)0)) _g_boolean_var_22 = 1; else _g_boolean_var_22
= 0; _g_boolean_var_22; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_23
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_23
= 1; else _g_boolean_var_23 = 0; _g_boolean_var_23; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_24
; if (concrete_mods != ((void*)0)) _g_boolean_var_24 = 1; else
_g_boolean_var_24 = 0; _g_boolean_var_24; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_25
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_25
= 1; else _g_boolean_var_25 = 0; _g_boolean_var_25; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_26
; if (virtual_mods != ((void*)0)) _g_boolean_var_26 = 1; else
_g_boolean_var_26 = 0; _g_boolean_var_26; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_27
; if (modmap != ((void*)0)) _g_boolean_var_27 = 1; else _g_boolean_var_27
= 0; _g_boolean_var_27; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-1f618a.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-1f618a.html new file mode 100644 index 0000000..784679d --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-1f618a.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_27
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_27
= 1; else _g_boolean_var_27 = 0; _g_boolean_var_27; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_28
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_28
= 1; else _g_boolean_var_28 = 0; _g_boolean_var_28; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_29
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_29
= 1; else _g_boolean_var_29 = 0; _g_boolean_var_29; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_30
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_30
= 1; else _g_boolean_var_30 = 0; _g_boolean_var_30; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_31
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_31
= 1; else _g_boolean_var_31 = 0; _g_boolean_var_31; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_32
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_32
= 1; else _g_boolean_var_32 = 0; _g_boolean_var_32; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_33
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_33
= 1; else _g_boolean_var_33 = 0; _g_boolean_var_33; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_34
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_34
= 1; else _g_boolean_var_34 = 0; _g_boolean_var_34; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) ((
window))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_35
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_35
= 1; else _g_boolean_var_35 = 0; _g_boolean_var_35; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } }
while (0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_36
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_36
= 1; else _g_boolean_var_36 = 0; _g_boolean_var_36; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) ((
window))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_37
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_37
= 1; else _g_boolean_var_37 = 0; _g_boolean_var_37; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_38
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_38
= 1; else _g_boolean_var_38 = 0; _g_boolean_var_38; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) ((window))))), "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_39
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_39
= 1; else _g_boolean_var_39 = 0; _g_boolean_var_39; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_40
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_40
= 1; else _g_boolean_var_40 = 0; _g_boolean_var_40; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_41
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_41
= 1; else _g_boolean_var_41 = 0; _g_boolean_var_41; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } }
while (0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_42
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_42
= 1; else _g_boolean_var_42 = 0; _g_boolean_var_42; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_43
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_43 = 1; else _g_boolean_var_43 = 0
; _g_boolean_var_43; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-37b917.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-37b917.html new file mode 100644 index 0000000..b602019 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-37b917.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_76
; if (accelerator != ((void*)0)) _g_boolean_var_76 = 1; else _g_boolean_var_76
= 0; _g_boolean_var_76; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_77
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_77
= 1; else _g_boolean_var_77 = 0; _g_boolean_var_77; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_78
; if (concrete_mods != ((void*)0)) _g_boolean_var_78 = 1; else
_g_boolean_var_78 = 0; _g_boolean_var_78; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_79
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_79
= 1; else _g_boolean_var_79 = 0; _g_boolean_var_79; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_80
; if (virtual_mods != ((void*)0)) _g_boolean_var_80 = 1; else
_g_boolean_var_80 = 0; _g_boolean_var_80; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_81
; if (modmap != ((void*)0)) _g_boolean_var_81 = 1; else _g_boolean_var_81
= 0; _g_boolean_var_81; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-4bda9e.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-4bda9e.html new file mode 100644 index 0000000..baeb757 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-4bda9e.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_40
; if (accelerator != ((void*)0)) _g_boolean_var_40 = 1; else _g_boolean_var_40
= 0; _g_boolean_var_40; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_41
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_41
= 1; else _g_boolean_var_41 = 0; _g_boolean_var_41; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_42
; if (concrete_mods != ((void*)0)) _g_boolean_var_42 = 1; else
_g_boolean_var_42 = 0; _g_boolean_var_42; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_43
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_43
= 1; else _g_boolean_var_43 = 0; _g_boolean_var_43; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_44
; if (virtual_mods != ((void*)0)) _g_boolean_var_44 = 1; else
_g_boolean_var_44 = 0; _g_boolean_var_44; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_45
; if (modmap != ((void*)0)) _g_boolean_var_45 = 1; else _g_boolean_var_45
= 0; _g_boolean_var_45; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-678a90.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-678a90.html new file mode 100644 index 0000000..52f1c03 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-678a90.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_64
; if (accelerator != ((void*)0)) _g_boolean_var_64 = 1; else _g_boolean_var_64
= 0; _g_boolean_var_64; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_65
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_65
= 1; else _g_boolean_var_65 = 0; _g_boolean_var_65; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_66
; if (concrete_mods != ((void*)0)) _g_boolean_var_66 = 1; else
_g_boolean_var_66 = 0; _g_boolean_var_66; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_67
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_67
= 1; else _g_boolean_var_67 = 0; _g_boolean_var_67; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_68
; if (virtual_mods != ((void*)0)) _g_boolean_var_68 = 1; else
_g_boolean_var_68 = 0; _g_boolean_var_68; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_69
; if (modmap != ((void*)0)) _g_boolean_var_69 = 1; else _g_boolean_var_69
= 0; _g_boolean_var_69; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-6fb882.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-6fb882.html new file mode 100644 index 0000000..9d4ecdf --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-6fb882.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_16
; if (accelerator != ((void*)0)) _g_boolean_var_16 = 1; else _g_boolean_var_16
= 0; _g_boolean_var_16; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_17
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_17
= 1; else _g_boolean_var_17 = 0; _g_boolean_var_17; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_18
; if (concrete_mods != ((void*)0)) _g_boolean_var_18 = 1; else
_g_boolean_var_18 = 0; _g_boolean_var_18; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_19
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_19
= 1; else _g_boolean_var_19 = 0; _g_boolean_var_19; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_20
; if (virtual_mods != ((void*)0)) _g_boolean_var_20 = 1; else
_g_boolean_var_20 = 0; _g_boolean_var_20; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_21
; if (modmap != ((void*)0)) _g_boolean_var_21 = 1; else _g_boolean_var_21
= 0; _g_boolean_var_21; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-7534c9.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-7534c9.html new file mode 100644 index 0000000..421aec4 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-7534c9.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_34
; if (accelerator != ((void*)0)) _g_boolean_var_34 = 1; else _g_boolean_var_34
= 0; _g_boolean_var_34; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_35
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_35
= 1; else _g_boolean_var_35 = 0; _g_boolean_var_35; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_36
; if (concrete_mods != ((void*)0)) _g_boolean_var_36 = 1; else
_g_boolean_var_36 = 0; _g_boolean_var_36; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_37
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_37
= 1; else _g_boolean_var_37 = 0; _g_boolean_var_37; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_38
; if (virtual_mods != ((void*)0)) _g_boolean_var_38 = 1; else
_g_boolean_var_38 = 0; _g_boolean_var_38; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_39
; if (modmap != ((void*)0)) _g_boolean_var_39 = 1; else _g_boolean_var_39
= 0; _g_boolean_var_39; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-85a3e8.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-85a3e8.html new file mode 100644 index 0000000..76463f3 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-85a3e8.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_70
; if (accelerator != ((void*)0)) _g_boolean_var_70 = 1; else _g_boolean_var_70
= 0; _g_boolean_var_70; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_71
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_71
= 1; else _g_boolean_var_71 = 0; _g_boolean_var_71; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_72
; if (concrete_mods != ((void*)0)) _g_boolean_var_72 = 1; else
_g_boolean_var_72 = 0; _g_boolean_var_72; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_73
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_73
= 1; else _g_boolean_var_73 = 0; _g_boolean_var_73; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_74
; if (virtual_mods != ((void*)0)) _g_boolean_var_74 = 1; else
_g_boolean_var_74 = 0; _g_boolean_var_74; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_75
; if (modmap != ((void*)0)) _g_boolean_var_75 = 1; else _g_boolean_var_75
= 0; _g_boolean_var_75; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-90bf5a.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-90bf5a.html new file mode 100644 index 0000000..76f919b --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-90bf5a.html @@ -0,0 +1,1177 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 467, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c maximus-bind.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#if HAVE_CONFIG_H1
22#include <config.h>
23#endif
24#include <stdio.h>
25#include <string.h>
26
27#include <gtk/gtk.h>
28#include <gdk/gdkx.h>
29
30#include <gdk/gdkkeysyms.h>
31
32#include <gio/gio.h>
33
34#define WNCK_I_KNOW_THIS_IS_UNSTABLE
35#include <libwnck/libwnck.h>
36
37#include <X11/Xlib.h>
38#include <X11/Xresource.h>
39#include <X11/Xutil.h>
40#include <X11/extensions/XTest.h>
41#include <X11/keysymdef.h>
42#include <X11/keysym.h>
43
44#include <fakekey/fakekey.h>
45
46#include "maximus-bind.h"
47
48#include "tomboykeybinder.h"
49#include "eggaccelerators.h"
50
51#define KEY_RELEASE_TIMEOUT300 300
52#define STATE_CHANGED_SLEEP0.5 0.5
53
54/* GSettings schemas and keys */
55#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
56#define BIND_EXCLUDE_CLASS"binding" "binding"
57
58#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
59
60#ifdef __GNUC__4
61#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
62#else
63#define UNUSED_VARIABLE__attribute__ ((unused))
64#endif
65
66struct _MaximusBindPrivate
67{
68 FakeKey *fk;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar *binding;
73
74 GList *rules;
75};
76
77typedef struct
78{
79 gchar *wm_class;
80 gchar *fullscreen;
81 gchar *unfullscreen;
82} MaximusRule;
83
84G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
85
86static const gchar *
87get_fullscreen_keystroke (GList *rules, WnckWindow *window)
88{
89 WnckClassGroup *group;
90 const gchar *class_name;
91 GList *r;
92
93 group = wnck_window_get_class_group (window);
94 class_name = wnck_class_group_get_name (group);
95
96 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
97
98 for (r = rules; r; r = r->next)
99 {
100 MaximusRule *rule = r->data;
101
102 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
103
104 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
105 {
106 g_debug ("\tYES!\n");
107 return rule->fullscreen;
108 }
109 g_debug ("\tNO!\n");
110 }
111
112 return NULL((void*)0);
113}
114
115static const gchar *
116get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
117{
118 WnckClassGroup *group;
119 const gchar *class_name;
120 GList *r;
121
122 group = wnck_window_get_class_group (window);
123 class_name = wnck_class_group_get_name (group);
124
125 for (r = rules; r; r = r->next)
126 {
127 MaximusRule *rule = r->data;
128
129 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
130 {
131 return rule->unfullscreen;
132 }
133 }
134
135 return NULL((void*)0);
136}
137static gboolean
138real_fullscreen (MaximusBind *bind)
139{
140 MaximusBindPrivate *priv;
141 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
142 WnckWindow *active;
143 const gchar *keystroke;
144
145 priv = bind->priv;
146
147 display = gdk_display_get_default ();
148 active = wnck_screen_get_active_window (priv->screen);
149
150 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
151 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
152 return FALSE(0);
153
154 keystroke = get_fullscreen_keystroke (priv->rules, active);
155
156 if (keystroke)
157 {
158 guint keysym = 0;
159 EggVirtualModifierType modifiers = 0;
160
161 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
162 {
163 guint mods = 0;
164
165 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
166 mods |= FAKEKEYMOD_SHIFT;
167 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
168 mods |= FAKEKEYMOD_CONTROL;
169 if (modifiers & EGG_VIRTUAL_ALT_MASK)
170 mods |= FAKEKEYMOD_ALT;
171 if (modifiers & EGG_VIRTUAL_META_MASK)
172 mods |= FAKEKEYMOD_META;
173
174 g_debug ("Sending fullscreen special event: %s = %d %d",
175 keystroke, keysym, mods);
176 fakekey_press_keysym (priv->fk, keysym, mods);
177 fakekey_release (priv->fk);
178
179 return FALSE(0);
180 }
181 }
182
183 if (!wnck_window_is_fullscreen (active))
184 {
185 g_debug ("Sending fullscreen F11 event");
186 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
187 fakekey_release (priv->fk);
188 }
189
190 sleep (STATE_CHANGED_SLEEP0.5);
191
192 if (!wnck_window_is_fullscreen (active))
193 {
194 g_debug ("Forcing fullscreen wnck event");
195 wnck_window_set_fullscreen (active, TRUE(!(0)));
196 }
197
198 return FALSE(0);
199}
200
201static void
202fullscreen (MaximusBind *bind, WnckWindow *window)
203{
204 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
205
206 priv = bind->priv;
207
208 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
209}
210
211static gboolean
212real_unfullscreen (MaximusBind *bind)
213{
214 MaximusBindPrivate *priv;
215 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
216 WnckWindow *active;
217 const gchar *keystroke;
218
219 priv = bind->priv;
220
221 display = gdk_display_get_default ();
222 active = wnck_screen_get_active_window (priv->screen);
223
224 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
225 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
226 return FALSE(0);
227
228 keystroke = get_unfullscreen_keystroke (priv->rules, active);
229
230 if (keystroke)
231 {
232 guint keysym = 0;
233 EggVirtualModifierType modifiers = 0;
234
235 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
236 {
237 guint mods = 0;
238
239 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
240 mods |= FAKEKEYMOD_SHIFT;
241 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
242 mods |= FAKEKEYMOD_CONTROL;
243 if (modifiers & EGG_VIRTUAL_ALT_MASK)
244 mods |= FAKEKEYMOD_ALT;
245 if (modifiers & EGG_VIRTUAL_META_MASK)
246 mods |= FAKEKEYMOD_META;
247
248 g_debug ("Sending fullscreen special event: %s = %d %d",
249 keystroke, keysym, mods);
250 fakekey_press_keysym (priv->fk, keysym, mods);
251 fakekey_release (priv->fk);
252
253 return FALSE(0);
254 }
255 }
256 if (wnck_window_is_fullscreen (active))
257 {
258 g_debug ("Sending un-fullscreen F11 event");
259 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
260 fakekey_release (priv->fk);
261 }
262
263 sleep (STATE_CHANGED_SLEEP0.5);
264
265 if (wnck_window_is_fullscreen (active))
266 {
267 g_debug ("Forcing un-fullscreen wnck event");
268 wnck_window_set_fullscreen (active, FALSE(0));
269 }
270
271 return FALSE(0);
272}
273
274static void
275unfullscreen (MaximusBind *bind, WnckWindow *window)
276{
277 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
278
279 priv = bind->priv;
280
281 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
282}
283
284static void
285on_binding_activated (gchar *keystring, MaximusBind *bind)
286{
287 MaximusBindPrivate *priv;
288 WnckWindow *active;
289
290 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_13
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_13
= 1; else _g_boolean_var_13 = 0; _g_boolean_var_13; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
291 priv = bind->priv;
292
293 active = wnck_screen_get_active_window (priv->screen);
294
295 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
296 return;
297
298 if (wnck_window_is_fullscreen (active))
299 {
300 unfullscreen (bind, active);
301 }
302 else
303 {
304 fullscreen (bind, active);
305 }
306}
307
308/* Callbacks */
309static gboolean
310binding_is_valid (const gchar *binding)
311{
312 gboolean retval = TRUE(!(0));
313
314 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
315 retval = FALSE(0);
316
317 return retval;
318}
319
320static void
321on_binding_changed (GSettings *settings,
322 gchar *key,
323 MaximusBind *bind)
324{
325 MaximusBindPrivate *priv;
326
327 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_14
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_14
= 1; else _g_boolean_var_14 = 0; _g_boolean_var_14; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
328 priv = bind->priv;
329
330 if (binding_is_valid (priv->binding))
331 tomboy_keybinder_unbind (priv->binding,
332 (TomboyBindkeyHandler)on_binding_changed);
333 g_free (priv->binding);
334
335 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
336
337 if (binding_is_valid (priv->binding))
338 tomboy_keybinder_bind (priv->binding,
339 (TomboyBindkeyHandler)on_binding_activated,
340 bind);
341
342 g_print ("Binding changed: %s\n", priv->binding);
343}
344
345/* GObject stuff */
346static void
347create_rule (MaximusBind *bind, const gchar *filename)
348{
349#define RULE_GROUP"Fullscreening" "Fullscreening"
350#define RULE_WMCLASS"WMClass" "WMClass"
351#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
352#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
353 MaximusBindPrivate *priv;
354 GKeyFile *file;
355 GError *error = NULL((void*)0);
356 MaximusRule *rule;
357
358 priv = bind->priv;
359
360 file = g_key_file_new ();
361 g_key_file_load_from_file (file, filename, 0, &error);
362 if (error)
363 {
364 g_warning ("Unable to load %s: %s\n", filename, error->message);
365 g_error_free (error);
366 g_key_file_free (file);
367 return;
368 }
369
370 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
371
372 rule->wm_class = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
374 NULL((void*)0));
375 rule->fullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
377 NULL((void*)0));
378 rule->unfullscreen = g_key_file_get_string (file,
379 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
380 NULL((void*)0));
381 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
382 {
383 g_free (rule->wm_class);
384 g_free (rule->fullscreen);
385 g_free (rule->unfullscreen);
386 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
387
388 g_warning ("Unable to load %s, missing strings", filename);
389 }
390 else
391 priv->rules = g_list_append (priv->rules, rule);
392
393 g_key_file_free (file);
394}
395
396static void
397load_rules (MaximusBind *bind, const gchar *path)
398{
399 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
400 GDir *dir;
401 const gchar *name;
402
403 priv = bind->priv;
404
405 dir = g_dir_open (path, 0, NULL((void*)0));
406
407 if (!dir)
408 return;
409
410 while ((name = g_dir_read_name (dir)))
411 {
412 gchar *filename;
413
414 filename= g_build_filename (path, name, NULL((void*)0));
415
416 create_rule (bind, filename);
417
418 g_free (filename);
419 }
420
421 g_dir_close (dir);
422}
423
424static void
425maximus_bind_finalize (GObject *obj)
426{
427 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) (void *) ((obj)))));
428 MaximusBindPrivate *priv;
429 GList *r;
430
431 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_15
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_15
= 1; else _g_boolean_var_15 = 0; _g_boolean_var_15; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
432 priv = bind->priv;
433
434 for (r = priv->rules; r; r = r->next)
435 {
436 MaximusRule *rule = r->data;
437
438 g_free (rule->wm_class);
439 g_free (rule->fullscreen);
440 g_free (rule->unfullscreen);
441
442 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
443 }
444 g_free (priv->binding);
445
446 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) (void *) ((maximus_bind_parent_class)))))->finalize (obj);
447}
448
449static void
450maximus_bind_class_init (MaximusBindClass *klass)
451{
452 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) ((klass)))));
453
454 obj_class->finalize = maximus_bind_finalize;
455}
456
457static void
458maximus_bind_init (MaximusBind *bind)
459{
460 MaximusBindPrivate *priv;
461 GdkDisplay *display = gdk_display_get_default ();
462 WnckScreen *screen;
463
464 priv = bind->priv = maximus_bind_get_instance_private (bind);
465
466 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
467 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
468 priv->rules = NULL((void*)0);
469 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
470
471 tomboy_keybinder_init ();
472
473 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
474 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
475
476 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
477
478 if (binding_is_valid (priv->binding))
479 tomboy_keybinder_bind (priv->binding,
480 (TomboyBindkeyHandler)on_binding_activated,
481 bind);
482
483 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
484}
485
486MaximusBind *
487maximus_bind_get_default (void)
488
489{
490 static MaximusBind *bind = NULL((void*)0);
491
492 if (!bind)
493 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
494 NULL((void*)0));
495
496 return bind;
497}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-aa2062.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-aa2062.html new file mode 100644 index 0000000..0f3092b --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-aa2062.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_28
; if (accelerator != ((void*)0)) _g_boolean_var_28 = 1; else _g_boolean_var_28
= 0; _g_boolean_var_28; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_29
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_29
= 1; else _g_boolean_var_29 = 0; _g_boolean_var_29; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_30
; if (concrete_mods != ((void*)0)) _g_boolean_var_30 = 1; else
_g_boolean_var_30 = 0; _g_boolean_var_30; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_31
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_31
= 1; else _g_boolean_var_31 = 0; _g_boolean_var_31; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_32
; if (virtual_mods != ((void*)0)) _g_boolean_var_32 = 1; else
_g_boolean_var_32 = 0; _g_boolean_var_32; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_33
; if (modmap != ((void*)0)) _g_boolean_var_33 = 1; else _g_boolean_var_33
= 0; _g_boolean_var_33; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-b10f27.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-b10f27.html new file mode 100644 index 0000000..063f4c2 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-b10f27.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_52
; if (accelerator != ((void*)0)) _g_boolean_var_52 = 1; else _g_boolean_var_52
= 0; _g_boolean_var_52; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_53
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_53
= 1; else _g_boolean_var_53 = 0; _g_boolean_var_53; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_54
; if (concrete_mods != ((void*)0)) _g_boolean_var_54 = 1; else
_g_boolean_var_54 = 0; _g_boolean_var_54; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_55
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_55
= 1; else _g_boolean_var_55 = 0; _g_boolean_var_55; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_56
; if (virtual_mods != ((void*)0)) _g_boolean_var_56 = 1; else
_g_boolean_var_56 = 0; _g_boolean_var_56; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_57
; if (modmap != ((void*)0)) _g_boolean_var_57 = 1; else _g_boolean_var_57
= 0; _g_boolean_var_57; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-c2cf20.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-c2cf20.html new file mode 100644 index 0000000..3fc2dcc --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-c2cf20.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_58
; if (accelerator != ((void*)0)) _g_boolean_var_58 = 1; else _g_boolean_var_58
= 0; _g_boolean_var_58; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_59
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_59
= 1; else _g_boolean_var_59 = 0; _g_boolean_var_59; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_60
; if (concrete_mods != ((void*)0)) _g_boolean_var_60 = 1; else
_g_boolean_var_60 = 0; _g_boolean_var_60; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_61
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_61
= 1; else _g_boolean_var_61 = 0; _g_boolean_var_61; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_62
; if (virtual_mods != ((void*)0)) _g_boolean_var_62 = 1; else
_g_boolean_var_62 = 0; _g_boolean_var_62; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_63
; if (modmap != ((void*)0)) _g_boolean_var_63 = 1; else _g_boolean_var_63
= 0; _g_boolean_var_63; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e3bdb1.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e3bdb1.html new file mode 100644 index 0000000..64cef67 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e3bdb1.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_82
; if (accelerator != ((void*)0)) _g_boolean_var_82 = 1; else _g_boolean_var_82
= 0; _g_boolean_var_82; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_83
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_83
= 1; else _g_boolean_var_83 = 0; _g_boolean_var_83; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_84
; if (concrete_mods != ((void*)0)) _g_boolean_var_84 = 1; else
_g_boolean_var_84 = 0; _g_boolean_var_84; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_85
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_85
= 1; else _g_boolean_var_85 = 0; _g_boolean_var_85; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_86
; if (virtual_mods != ((void*)0)) _g_boolean_var_86 = 1; else
_g_boolean_var_86 = 0; _g_boolean_var_86; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_87
; if (modmap != ((void*)0)) _g_boolean_var_87 = 1; else _g_boolean_var_87
= 0; _g_boolean_var_87; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e9ff85.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e9ff85.html new file mode 100644 index 0000000..468bd7d --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e9ff85.html @@ -0,0 +1,1228 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c maximus-app.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_44
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_44
= 1; else _g_boolean_var_44 = 0; _g_boolean_var_44; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_45
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_45
= 1; else _g_boolean_var_45 = 0; _g_boolean_var_45; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_46
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_46
= 1; else _g_boolean_var_46 = 0; _g_boolean_var_46; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_47
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_47
= 1; else _g_boolean_var_47 = 0; _g_boolean_var_47; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_48
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_48
= 1; else _g_boolean_var_48 = 0; _g_boolean_var_48; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_49
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_49
= 1; else _g_boolean_var_49 = 0; _g_boolean_var_49; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_50
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_50
= 1; else _g_boolean_var_50 = 0; _g_boolean_var_50; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } }
while (0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_51
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_51
= 1; else _g_boolean_var_51 = 0; _g_boolean_var_51; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) ((
window))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_52
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_52
= 1; else _g_boolean_var_52 = 0; _g_boolean_var_52; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } }
while (0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_53
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_53
= 1; else _g_boolean_var_53 = 0; _g_boolean_var_53; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) ((
window))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_54
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_54
= 1; else _g_boolean_var_54 = 0; _g_boolean_var_54; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_55
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_55
= 1; else _g_boolean_var_55 = 0; _g_boolean_var_55; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while
(0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) ((window))))), "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_56
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_56
= 1; else _g_boolean_var_56 = 0; _g_boolean_var_56; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_57
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_57
= 1; else _g_boolean_var_57 = 0; _g_boolean_var_57; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_58
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_58
= 1; else _g_boolean_var_58 = 0; _g_boolean_var_58; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } }
while (0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_59
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_59
= 1; else _g_boolean_var_59 = 0; _g_boolean_var_59; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0
)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_60
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_60 = 1; else _g_boolean_var_60 = 0
; _g_boolean_var_60; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-faab40.html b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-faab40.html new file mode 100644 index 0000000..eaec1a2 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-faab40.html @@ -0,0 +1,1336 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-030840-5334-1 -x c eggaccelerators.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_46
; if (accelerator != ((void*)0)) _g_boolean_var_46 = 1; else _g_boolean_var_46
= 0; _g_boolean_var_46; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_47
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_47
= 1; else _g_boolean_var_47 = 0; _g_boolean_var_47; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_48
; if (concrete_mods != ((void*)0)) _g_boolean_var_48 = 1; else
_g_boolean_var_48 = 0; _g_boolean_var_48; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "concrete_mods != NULL"); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_49
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_49
= 1; else _g_boolean_var_49 = 0; _g_boolean_var_49; }), 1)))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_50
; if (virtual_mods != ((void*)0)) _g_boolean_var_50 = 1; else
_g_boolean_var_50 = 0; _g_boolean_var_50; }), 1))) { } else {
g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "virtual_mods != NULL"); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) (void *) ((keymap))))),
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_51
; if (modmap != ((void*)0)) _g_boolean_var_51 = 1; else _g_boolean_var_51
= 0; _g_boolean_var_51; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/scanview.css b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/sorttable.js b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2023-07-21-030840-5334-1@6b49a8c0d49d_meson/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
/* eggaccelerators.c
+ * Copyright (C) 2002  Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Copyright (C) 2012-2021 MATE Developers
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+  EGG_MODMAP_ENTRY_SHIFT   = 0,
+  EGG_MODMAP_ENTRY_LOCK    = 1,
+  EGG_MODMAP_ENTRY_CONTROL = 2,
+  EGG_MODMAP_ENTRY_MOD1    = 3,
+  EGG_MODMAP_ENTRY_MOD2    = 4,
+  EGG_MODMAP_ENTRY_MOD3    = 5,
+  EGG_MODMAP_ENTRY_MOD4    = 6,
+  EGG_MODMAP_ENTRY_MOD5    = 7,
+  EGG_MODMAP_ENTRY_LAST    = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+  EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+static inline gboolean
+is_alt (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'a' || string[1] == 'A') &&
+	  (string[2] == 'l' || string[2] == 'L') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_ctl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == '>'));
+}
+
+static inline gboolean
+is_modx (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'd' || string[3] == 'D') &&
+	  (string[4] >= '1' && string[4] <= '5') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_ctrl (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 't' || string[2] == 'T') &&
+	  (string[3] == 'r' || string[3] == 'R') &&
+	  (string[4] == 'l' || string[4] == 'L') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shft (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'f' || string[3] == 'F') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_shift (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'h' || string[2] == 'H') &&
+	  (string[3] == 'i' || string[3] == 'I') &&
+	  (string[4] == 'f' || string[4] == 'F') &&
+	  (string[5] == 't' || string[5] == 'T') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_control (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'c' || string[1] == 'C') &&
+	  (string[2] == 'o' || string[2] == 'O') &&
+	  (string[3] == 'n' || string[3] == 'N') &&
+	  (string[4] == 't' || string[4] == 'T') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == 'o' || string[6] == 'O') &&
+	  (string[7] == 'l' || string[7] == 'L') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_release (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'r' || string[1] == 'R') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 'l' || string[3] == 'L') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'a' || string[5] == 'A') &&
+	  (string[6] == 's' || string[6] == 'S') &&
+	  (string[7] == 'e' || string[7] == 'E') &&
+	  (string[8] == '>'));
+}
+
+static inline gboolean
+is_meta (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'm' || string[1] == 'M') &&
+	  (string[2] == 'e' || string[2] == 'E') &&
+	  (string[3] == 't' || string[3] == 'T') &&
+	  (string[4] == 'a' || string[4] == 'A') &&
+	  (string[5] == '>'));
+}
+
+static inline gboolean
+is_super (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 's' || string[1] == 'S') &&
+	  (string[2] == 'u' || string[2] == 'U') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+static inline gboolean
+is_hyper (const gchar *string)
+{
+  return ((string[0] == '<') &&
+	  (string[1] == 'h' || string[1] == 'H') &&
+	  (string[2] == 'y' || string[2] == 'Y') &&
+	  (string[3] == 'p' || string[3] == 'P') &&
+	  (string[4] == 'e' || string[4] == 'E') &&
+	  (string[5] == 'r' || string[5] == 'R') &&
+	  (string[6] == '>'));
+}
+
+/**
+ * egg_accelerator_parse_virtual:
+ * @accelerator:      string representing an accelerator
+ * @accelerator_key:  return location for accelerator keyval
+ * @accelerator_mods: return location for accelerator modifier mask
+ *
+ * Parses a string representing a virtual accelerator. The format
+ * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).  The parser
+ * is fairly liberal and allows lower or upper case, and also
+ * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
+ *
+ * If the parse fails, @accelerator_key and @accelerator_mods will
+ * be set to 0 (zero) and %FALSE will be returned. If the string contains
+ * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
+ * returned.
+ *
+ * The virtual vs. concrete accelerator distinction is a relic of
+ * how the X Window System works; there are modifiers Mod2-Mod5 that
+ * can represent various keyboard keys (numlock, meta, hyper, etc.),
+ * the virtual modifier represents the keyboard key, the concrete
+ * modifier the actual Mod2-Mod5 bits in the key press event.
+ * 
+ * Returns: %TRUE on success.
+ */
+gboolean
+egg_accelerator_parse_virtual (const gchar            *accelerator,
+                               guint                  *accelerator_key,
+                               EggVirtualModifierType *accelerator_mods)
+{
+  guint keyval;
+  GdkModifierType mods;
+  gint len;
+  gboolean bad_keyval;
+  
+  if (accelerator_key)
+    *accelerator_key = 0;
+  if (accelerator_mods)
+    *accelerator_mods = 0;
+
+  g_return_val_if_fail (accelerator != NULL, FALSE);
+
+  bad_keyval = FALSE;
+  
+  keyval = 0;
+  mods = 0;
+  len = strlen (accelerator);
+  while (len)
+    {
+      if (*accelerator == '<')
+	{
+	  if (len >= 9 && is_release (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_RELEASE_MASK;
+	    }
+	  else if (len >= 9 && is_control (accelerator))
+	    {
+	      accelerator += 9;
+	      len -= 9;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 7 && is_shift (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_shft (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_SHIFT_MASK;
+	    }
+	  else if (len >= 6 && is_ctrl (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 6 && is_modx (accelerator))
+	    {
+	      static const guint mod_vals[] = {
+		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
+		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
+	      };
+
+	      len -= 6;
+	      accelerator += 4;
+	      mods |= mod_vals[*accelerator - '1'];
+	      accelerator += 2;
+	    }
+	  else if (len >= 5 && is_ctl (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_CONTROL_MASK;
+	    }
+	  else if (len >= 5 && is_alt (accelerator))
+	    {
+	      accelerator += 5;
+	      len -= 5;
+	      mods |= EGG_VIRTUAL_ALT_MASK;
+	    }
+          else if (len >= 6 && is_meta (accelerator))
+	    {
+	      accelerator += 6;
+	      len -= 6;
+	      mods |= EGG_VIRTUAL_META_MASK;
+	    }
+          else if (len >= 7 && is_hyper (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_HYPER_MASK;
+	    }
+          else if (len >= 7 && is_super (accelerator))
+	    {
+	      accelerator += 7;
+	      len -= 7;
+	      mods |= EGG_VIRTUAL_SUPER_MASK;
+	    }
+	  else
+	    {
+	      gchar last_ch;
+	      
+	      last_ch = *accelerator;
+	      while (last_ch && last_ch != '>')
+		{
+		  last_ch = *accelerator;
+		  accelerator += 1;
+		  len -= 1;
+		}
+	    }
+	}
+      else
+	{
+          keyval = gdk_keyval_from_name (accelerator);
+          
+          if (keyval == 0)
+            bad_keyval = TRUE;
+          
+          accelerator += len;
+          len -= len;              
+	}
+    }
+  
+  if (accelerator_key)
+    *accelerator_key = gdk_keyval_to_lower (keyval);
+  if (accelerator_mods)
+    *accelerator_mods = mods;
+
+  return !bad_keyval;
+}
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key:  accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns:          a newly-allocated accelerator name
+ * 
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "&lt;Control&gt;q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar*
+egg_virtual_accelerator_name (guint                  accelerator_key,
+                              EggVirtualModifierType accelerator_mods)
+{
+  static const gchar text_release[] = "<Release>";
+  static const gchar text_shift[] = "<Shift>";
+  static const gchar text_control[] = "<Control>";
+  static const gchar text_mod1[] = "<Alt>";
+  static const gchar text_mod2[] = "<Mod2>";
+  static const gchar text_mod3[] = "<Mod3>";
+  static const gchar text_mod4[] = "<Mod4>";
+  static const gchar text_mod5[] = "<Mod5>";
+  static const gchar text_meta[] = "<Meta>";
+  static const gchar text_super[] = "<Super>";
+  static const gchar text_hyper[] = "<Hyper>";
+  guint l;
+  gchar *keyval_name;
+  gchar *accelerator;
+
+  accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+  keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+  if (!keyval_name)
+    keyval_name = "";
+
+  l = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    l += sizeof (text_release) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    l += sizeof (text_shift) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    l += sizeof (text_control) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    l += sizeof (text_mod1) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    l += sizeof (text_mod2) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    l += sizeof (text_mod3) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    l += sizeof (text_mod4) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    l += sizeof (text_mod5) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    l += sizeof (text_meta) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    l += sizeof (text_hyper) - 1;
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    l += sizeof (text_super) - 1;
+  l += strlen (keyval_name);
+
+  accelerator = g_new (gchar, l + 1);
+
+  l = 0;
+  accelerator[l] = 0;
+  if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+    {
+      strcpy (accelerator + l, text_release);
+      l += sizeof (text_release) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+    {
+      strcpy (accelerator + l, text_shift);
+      l += sizeof (text_shift) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+    {
+      strcpy (accelerator + l, text_control);
+      l += sizeof (text_control) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+    {
+      strcpy (accelerator + l, text_mod1);
+      l += sizeof (text_mod1) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+    {
+      strcpy (accelerator + l, text_mod2);
+      l += sizeof (text_mod2) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+    {
+      strcpy (accelerator + l, text_mod3);
+      l += sizeof (text_mod3) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+    {
+      strcpy (accelerator + l, text_mod4);
+      l += sizeof (text_mod4) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+    {
+      strcpy (accelerator + l, text_mod5);
+      l += sizeof (text_mod5) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+    {
+      strcpy (accelerator + l, text_meta);
+      l += sizeof (text_meta) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+    {
+      strcpy (accelerator + l, text_hyper);
+      l += sizeof (text_hyper) - 1;
+    }
+  if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+    {
+      strcpy (accelerator + l, text_super);
+      l += sizeof (text_super) - 1;
+    }
+  
+  strcpy (accelerator + l, keyval_name);
+
+  return accelerator;
+}
+
+void
+egg_keymap_resolve_virtual_modifiers (GdkKeymap              *keymap,
+                                      EggVirtualModifierType  virtual_mods,
+                                      GdkModifierType        *concrete_mods)
+{
+  GdkModifierType concrete;
+  int i;
+  const EggModmap *modmap;
+
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (concrete_mods != NULL);
+  
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  concrete = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if (modmap->mapping[i] & virtual_mods)
+        concrete |= (1 << i);
+
+      ++i;
+    }
+
+  *concrete_mods = concrete;
+}
+
+void
+egg_keymap_virtualize_modifiers (GdkKeymap              *keymap,
+                                 GdkModifierType         concrete_mods,
+                                 EggVirtualModifierType *virtual_mods)
+{
+  GdkModifierType virtual;
+  int i;
+  const EggModmap *modmap;
+  
+  g_return_if_fail (GDK_IS_KEYMAP (keymap));
+  g_return_if_fail (virtual_mods != NULL);
+
+  modmap = egg_keymap_get_modmap (keymap);
+  
+  /* Not so sure about this algorithm. */
+  
+  virtual = 0;
+  i = 0;
+  while (i < EGG_MODMAP_ENTRY_LAST)
+    {
+      if ((1 << i) & concrete_mods)
+        {
+          EggVirtualModifierType cleaned;
+          
+          cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+                                           EGG_VIRTUAL_MOD3_MASK |
+                                           EGG_VIRTUAL_MOD4_MASK |
+                                           EGG_VIRTUAL_MOD5_MASK);
+          
+          if (cleaned != 0)
+            {
+              virtual |= cleaned;
+            }
+          else
+            {
+              /* Rather than dropping mod2->mod5 if not bound,
+               * go ahead and use the concrete names
+               */
+              virtual |= modmap->mapping[i];
+            }
+        }
+      
+      ++i;
+    }
+  
+  *virtual_mods = virtual;
+}
+
+static void
+reload_modmap (GdkKeymap *keymap,
+               EggModmap *modmap)
+{
+  XModifierKeymap *xmodmap;
+  int map_size;
+  int i;
+
+  /* FIXME multihead */
+  xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+  memset (modmap->mapping, 0, sizeof (modmap->mapping));
+  
+  /* there are 8 modifiers, and the first 3 are shift, shift lock,
+   * and control
+   */
+  map_size = 8 * xmodmap->max_keypermod;
+  i = 3 * xmodmap->max_keypermod;
+  while (i < map_size)
+    {
+      /* get the key code at this point in the map,
+       * see if its keysym is one we're interested in
+       */
+      int keycode = xmodmap->modifiermap[i];
+      GdkKeymapKey *keys;
+      guint *keyvals;
+      int n_entries;
+      int j;
+      EggVirtualModifierType mask;
+      
+      keys = NULL;
+      keyvals = NULL;
+      n_entries = 0;
+
+      gdk_keymap_get_entries_for_keycode (keymap,
+                                          keycode,
+                                          &keys, &keyvals, &n_entries);
+      
+      mask = 0;
+      j = 0;
+      while (j < n_entries)
+        {          
+          if (keyvals[j] == GDK_KEY_Num_Lock)
+            mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Scroll_Lock)
+            mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+          else if (keyvals[j] == GDK_KEY_Meta_L ||
+                   keyvals[j] == GDK_KEY_Meta_R)
+            mask |= EGG_VIRTUAL_META_MASK;
+          else if (keyvals[j] == GDK_KEY_Hyper_L ||
+                   keyvals[j] == GDK_KEY_Hyper_R)
+            mask |= EGG_VIRTUAL_HYPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Super_L ||
+                   keyvals[j] == GDK_KEY_Super_R)
+            mask |= EGG_VIRTUAL_SUPER_MASK;
+          else if (keyvals[j] == GDK_KEY_Mode_switch)
+            mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+          
+          ++j;
+        }
+
+      /* Mod1Mask is 1 << 3 for example, i.e. the
+       * fourth modifier, i / keyspermod is the modifier
+       * index
+       */      
+      modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+      
+      g_free (keyvals);
+      g_free (keys);      
+      
+      ++i;
+    }
+
+  /* Add in the not-really-virtual fixed entries */
+  modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+  modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+  
+  XFreeModifiermap (xmodmap);
+}
+
+const EggModmap*
+egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+  EggModmap *modmap;
+
+  /* This is all a hack, much simpler when we can just
+   * modify GDK directly.
+   */
+  
+  modmap = g_object_get_data (G_OBJECT (keymap),
+                              "egg-modmap");
+
+  if (modmap == NULL)
+    {
+      modmap = g_new0 (EggModmap, 1);
+
+      /* FIXME modify keymap change events with an event filter
+       * and force a reload if we get one
+       */
+      
+      reload_modmap (keymap, modmap);
+      
+      g_object_set_data_full (G_OBJECT (keymap),
+                              "egg-modmap",
+                              modmap,
+                              g_free);
+    }
+
+  g_assert (modmap != NULL);
+  
+  return modmap;
+}
+
+ +
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/1.html b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/1.html new file mode 100644 index 0000000..1b637bc --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/1.html @@ -0,0 +1,441 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+static gboolean version    = FALSE;
+gboolean no_maximize = FALSE;
+
+GOptionEntry entries[] =
+{
+ {
+   "version", 'v',
+   0, G_OPTION_ARG_NONE,
+   &version,
+   "Prints the version number", NULL
+ },
+ {
+   "no-maximize", 'm',
+   0, G_OPTION_ARG_NONE,
+   &no_maximize,
+   "Do not automatically maximize every window", NULL
+ },
+ {
+   NULL
+ }
+};
+
+gint main (gint argc, gchar *argv[])
+{
+  GApplication *application;
+  MaximusApp UNUSED_VARIABLE *app;
+  GOptionContext  *context;
+  GError *error = NULL;
+  GdkDisplay *gdk_display;
+
+  g_set_application_name ("Maximus");
+
+  gtk_init (&argc, &argv);
+
+  application = g_application_new ("com.canonical.Maximus", G_APPLICATION_FLAGS_NONE);
+
+  if (!g_application_register (application, NULL, &error))
+  {
+    g_warning ("%s", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  if (g_application_get_is_remote(application))
+  {
+    return 0;
+  }
+
+  context = g_option_context_new ("- Maximus");
+  g_option_context_add_main_entries (context, entries, "maximus");
+  g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_parse (context, &argc, &argv, NULL);
+  g_option_context_free(context);
+
+  gdk_display = gdk_display_get_default ();
+  gdk_x11_display_error_trap_push (gdk_display);
+  app = maximus_app_get_default ();<--- Variable 'app' is assigned a value that is never used.
+  gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}
+
+ +
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/2.html b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/2.html new file mode 100644 index 0000000..1b4d91c --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/2.html @@ -0,0 +1,1333 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+
+#include "maximus-app.h"
+#include "maximus-bind.h"
+#include "xutils.h"
+
+/* GSettings schemas and keys */
+#define APP_SCHEMA        "org.mate.maximus"
+#define APP_EXCLUDE_CLASS "exclude-class"
+#define APP_UNDECORATE    "undecorate"
+#define APP_NO_MAXIMIZE   "no-maximize"
+
+/* A set of default exceptions */
+static gchar *default_exclude_classes[] = 
+{
+  "Apport-gtk",
+  "Bluetooth-properties",
+  "Bluetooth-wizard",
+  "Download", /* Firefox Download Window */
+  "Ekiga",
+  "Extension", /* Firefox Add-Ons/Extension Window */
+  "Gcalctool",
+  "Gimp",
+  "Global", /* Firefox Error Console Window */
+  "Mate-dictionary",
+  "Mate-language-selector",
+  "Mate-nettool",
+  "Mate-volume-control",
+  "Kiten",
+  "Kmplot",
+  "Nm-editor",
+  "Pidgin",
+  "Polkit-mate-authorization",
+  "Update-manager",
+  "Skype",
+  "Toplevel", /* Firefox "Clear Private Data" Window */
+  "Transmission"
+};
+
+struct _MaximusAppPrivate
+{
+  MaximusBind *bind;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar **exclude_class_list;
+  gboolean undecorate;
+  gboolean no_maximize;
+};
+
+static GQuark was_decorated = 0;
+
+/* <TAKEN FROM GDK> */
+typedef struct {
+    unsigned long flags;
+    unsigned long functions;
+    unsigned long decorations;
+    long input_mode;
+    unsigned long status;
+} MotifWmHints, MwmHints;
+
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define _XA_MOTIF_WM_HINTS		"_MOTIF_WM_HINTS"
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT);
+
+static gboolean
+wnck_window_is_decorated (WnckWindow *window)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  gboolean retval;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  
+  if (type == None || !data) return TRUE;
+  
+  hints = (MotifWmHints *)data; 
+  
+  retval = hints->decorations;
+  
+  if (data)<--- Condition 'data' is always true
+    XFree (data);
+
+  return retval;
+}
+
+static void
+gdk_window_set_mwm_hints (WnckWindow *window,
+                          MotifWmHints *new_hints)
+{
+  GdkDisplay *display = gdk_display_get_default();
+  Atom hints_atom = None;
+  guchar *data = NULL;
+  MotifWmHints *hints = NULL;
+  Atom type = None;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  
+  hints_atom = gdk_x11_get_xatom_by_name_for_display (display, 
+                                                      _XA_MOTIF_WM_HINTS);
+
+  gdk_x11_display_error_trap_push (display);
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                      wnck_window_get_xid (window),
+		                  hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+		                  False, AnyPropertyType, &type, &format, &nitems,
+		                  &bytes_after, &data);
+  if (gdk_x11_display_error_trap_pop (display))
+    return;
+  
+  if (type != hints_atom || !data)
+    hints = new_hints;
+  else
+  {
+    hints = (MotifWmHints *)data;
+	
+    if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+    {
+      hints->flags |= MWM_HINTS_FUNCTIONS;
+      hints->functions = new_hints->functions;  
+    }
+    if (new_hints->flags & MWM_HINTS_DECORATIONS)
+    {
+      hints->flags |= MWM_HINTS_DECORATIONS;
+      hints->decorations = new_hints->decorations;
+    }
+  }
+  
+  _wnck_error_trap_push ();
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display), 
+                   wnck_window_get_xid (window),
+                   hints_atom, hints_atom, 32, PropModeReplace,
+                   (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+  gdk_display_flush (display);
+  _wnck_error_trap_pop ();
+  
+  if (data)
+    XFree (data);
+}
+
+static void
+_window_set_decorations (WnckWindow      *window,
+			                   GdkWMDecoration decorations)
+{
+  MotifWmHints *hints;
+  
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  /* initialize to zero to avoid writing uninitialized data to socket */
+  hints = g_slice_new0 (MotifWmHints);
+  hints->flags = MWM_HINTS_DECORATIONS;
+  hints->decorations = decorations;
+ 
+  gdk_window_set_mwm_hints (window, hints);
+
+  g_slice_free (MotifWmHints, hints);
+}
+
+/* </TAKEN FROM GDK> */
+
+gboolean
+window_is_too_large_for_screen (WnckWindow *window)
+{
+  static GdkScreen *screen = NULL;
+  gint x=0, y=0, w=0, h=0;
+
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (screen == NULL)
+    screen = gdk_screen_get_default ();
+    
+  wnck_window_get_geometry (window, &x, &y, &w, &h);
+  
+  /* some wiggle room */
+  return (screen && 
+          (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20) ||
+           h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 20)));
+}
+
+static gboolean
+on_window_maximised_changed (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  if (window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 1);
+      wnck_window_unmaximize (window);
+    }
+  else
+    {
+      _window_set_decorations (window, 0);
+    }
+  return FALSE;
+}
+
+static gboolean
+enable_window_decorations (WnckWindow *window)
+{
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+  _window_set_decorations (window, 1);
+  return FALSE;
+}
+
+static void
+on_window_state_changed (WnckWindow      *window,
+                         WnckWindowState  change_mask,
+                         WnckWindowState  new_state,
+                         MaximusApp     *app)
+{
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return;
+  
+  if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
+      || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
+  {
+    if (wnck_window_is_maximized (window) && app->priv->undecorate)
+    {
+      g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
+    }
+    else
+    {
+      g_idle_add ((GSourceFunc)enable_window_decorations, window);
+    }
+  }
+}
+
+static gboolean
+is_excluded (MaximusApp *app, WnckWindow *window)
+{
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  WnckWindowActions actions;
+  gchar *res_name;
+  gchar *class_name;
+  gint i;
+
+  g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE);
+  g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE);
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return TRUE;
+
+  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))==1)
+    return TRUE;
+
+  /* Ignore if the window is already fullscreen */
+  if (wnck_window_is_fullscreen (window))
+  {
+    g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
+    return TRUE;
+  }
+  
+  /* Make sure the window supports maximising */
+  actions = wnck_window_get_actions (window);
+  if (actions & WNCK_WINDOW_ACTION_RESIZE
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
+      && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
+    ; /* Is good to maximise */
+  else
+    return TRUE;
+
+  _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
+
+  g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
+ 
+  /* Check internal list of class_ids */
+  for (i = 0; i < G_N_ELEMENTS (default_exclude_classes); i++)
+  {
+    if ((class_name && default_exclude_classes[i] 
+        && strstr (class_name, default_exclude_classes[i]))
+        || (res_name && default_exclude_classes[i] && strstr (res_name, 
+                                            default_exclude_classes[i])))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    } 
+  }
+
+  /* Check user list */
+  for (i = 0; priv->exclude_class_list[i] != NULL; i++)
+  {
+    if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
+        || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
+    {
+      g_debug ("Excluding: %s\n", wnck_window_get_name (window));
+      return TRUE;
+    }
+  }
+
+  g_free (res_name);
+  g_free (class_name);
+  return FALSE;
+}
+
+extern gboolean no_maximize;
+
+static void
+on_window_opened (WnckScreen  *screen,
+                  WnckWindow  *window,
+                  MaximusApp *app)
+{ 
+  MaximusAppPrivate *priv;
+  WnckWindowType type;
+  gint exclude = 0;
+  GdkDisplay *gdk_display = gdk_display_get_default ();
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  priv = app->priv;
+
+  type = wnck_window_get_window_type (window);
+  if (type != WNCK_WINDOW_NORMAL)
+    return;
+
+  /* Ignore undecorated windows */
+  gdk_x11_display_error_trap_push (gdk_display);
+  exclude = wnck_window_is_decorated (window) ? 0 : 1;
+  if (gdk_x11_display_error_trap_pop (gdk_display))
+    return;
+
+  if (wnck_window_is_maximized (window))
+    exclude = 0;
+  g_object_set_data (G_OBJECT (window), "exclude", GINT_TO_POINTER (exclude));
+
+  if (is_excluded (app, window))
+  {
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (no_maximize || priv->no_maximize)
+  {
+    if (wnck_window_is_maximized(window) && priv->undecorate)
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+    g_signal_connect (window, "state-changed",
+                      G_CALLBACK (on_window_state_changed), app);
+    return;
+  }
+
+  if (priv->undecorate)
+  {
+    /* Only undecorate right now if the window is smaller than the screen */
+    if (!window_is_too_large_for_screen (window))
+    {
+      _window_set_decorations (window, 0);
+      gdk_display_flush (gdk_display);
+    }
+  }
+
+  wnck_window_maximize (window);
+
+  g_signal_connect (window, "state-changed",
+                    G_CALLBACK (on_window_state_changed), app);
+}
+
+/* GSettings Callbacks */
+static void
+on_app_no_maximize_changed (GSettings *settings,
+                            gchar *key,
+                            MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  priv->no_maximize = g_settings_get_boolean (settings, key);
+}
+
+static void
+on_exclude_class_changed (GSettings *settings,
+                          gchar *key,
+                          MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+
+  if (priv->exclude_class_list)
+    g_strfreev (priv->exclude_class_list);
+  
+  priv->exclude_class_list= g_settings_get_strv (settings, 
+                                                 APP_EXCLUDE_CLASS);
+}
+
+static gboolean
+show_desktop (WnckScreen *screen)
+{
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+  
+  wnck_screen_toggle_showing_desktop (screen, TRUE);
+  return FALSE;
+}
+
+static void
+on_app_undecorate_changed (GSettings          *settings,
+                           gchar              *key,
+                           MaximusApp         *app)
+{
+  MaximusAppPrivate *priv;
+  GList *windows, *w;
+    
+  g_return_if_fail (MAXIMUS_IS_APP (app));
+  priv = app->priv;
+  g_return_if_fail (WNCK_IS_SCREEN (priv->screen));
+
+  priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE);
+  g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
+  
+  windows = wnck_screen_get_windows (priv->screen);
+  for (w = windows; w; w = w->next)
+  {
+    WnckWindow *window = w->data;
+
+    if (!WNCK_IS_WINDOW (window))
+      continue;
+
+    if (no_maximize || priv->no_maximize)
+    {
+      if (!wnck_window_is_maximized(window))
+        continue;
+    }
+
+    if (!is_excluded (app, window))
+    {
+      GdkDisplay *gdk_display = gdk_display_get_default ();
+
+      gdk_x11_display_error_trap_push (gdk_display);
+      _window_set_decorations (window, priv->undecorate ? 0 : 1);
+      wnck_window_unmaximize (window);
+      wnck_window_maximize (window);
+      gdk_display_flush (gdk_display);
+      gdk_x11_display_error_trap_pop_ignored (gdk_display);
+
+      sleep (1);
+    }
+  }
+  /* We want the user to be left on the launcher/desktop after switching modes*/
+  g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
+}
+
+/* GObject stuff */
+static void
+maximus_app_class_init (MaximusAppClass *klass)
+{
+}
+
+static void
+maximus_app_init (MaximusApp *app)
+{
+  MaximusAppPrivate *priv;
+  WnckScreen *screen;
+	
+  priv = app->priv = maximus_app_get_instance_private (app);
+
+  priv->bind = maximus_bind_get_default ();
+
+  was_decorated = g_quark_from_static_string ("was-decorated");
+
+  priv->settings = g_settings_new (APP_SCHEMA);
+
+  g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,
+                    G_CALLBACK (on_exclude_class_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,
+                    G_CALLBACK (on_app_undecorate_changed), app);
+  g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,
+                    G_CALLBACK (on_app_no_maximize_changed), app);
+
+  priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS); 
+  priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE);
+  priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE);
+  g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
+ 
+  priv->screen = screen = wnck_screen_get_default ();
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), app);
+}
+
+MaximusApp *
+maximus_app_get_default (void)
+
+{
+  static MaximusApp *app = NULL;
+
+  if (!app)
+    app = g_object_new (MAXIMUS_TYPE_APP, 
+                        NULL);
+
+  return app;
+}
+
+ +
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/3.html b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/3.html new file mode 100644 index 0000000..0bf1826 --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/3.html @@ -0,0 +1,1231 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
/*
+ * Copyright (C) 2008 Canonical Ltd
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include <gio/gio.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#include "maximus-bind.h"
+
+#include "tomboykeybinder.h"
+#include "eggaccelerators.h"
+
+#define KEY_RELEASE_TIMEOUT 300
+#define STATE_CHANGED_SLEEP 0.5
+
+/* GSettings schemas and keys */
+#define BIND_SCHEMA        "org.mate.maximus"
+#define BIND_EXCLUDE_CLASS "binding"
+
+#define SYSRULESDIR SYSCONFDIR"/maximus"
+
+#ifdef __GNUC__
+#define UNUSED_VARIABLE __attribute__ ((unused))
+#else
+#define UNUSED_VARIABLE
+#endif
+
+struct _MaximusBindPrivate
+{
+  FakeKey *fk;
+  WnckScreen *screen;
+  GSettings *settings;
+
+  gchar *binding;
+
+  GList *rules;
+};
+
+typedef struct
+{
+  gchar *wm_class;
+  gchar *fullscreen;
+  gchar *unfullscreen;
+} MaximusRule;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT);
+
+static const gchar *
+get_fullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_debug ("\t%s ?= %s", class_name, rule->wm_class);
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      g_debug ("\tYES!\n");
+      return rule->fullscreen;
+    }
+    g_debug ("\tNO!\n");
+  }
+
+  return NULL;
+}
+
+static const gchar *
+get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
+{
+  WnckClassGroup *group;
+  const gchar *class_name;
+  GList *r;
+
+  group = wnck_window_get_class_group (window);
+  class_name = wnck_class_group_get_name (group);
+
+  for (r = rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
+    {
+      return rule->unfullscreen;
+    }
+  }
+
+  return NULL;
+}
+static gboolean
+real_fullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_fullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (!wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing fullscreen wnck event");
+    wnck_window_set_fullscreen (active, TRUE);
+  }
+
+  return FALSE;
+}
+
+static void
+fullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_fullscreen, bind);
+}
+
+static gboolean
+real_unfullscreen (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay UNUSED_VARIABLE *display;
+  WnckWindow *active;
+  const gchar *keystroke;
+
+  priv = bind->priv;
+
+  display = gdk_display_get_default ();<--- Variable 'display' is assigned a value that is never used.
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (!WNCK_IS_WINDOW (active)
+        || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return FALSE;
+
+  keystroke = get_unfullscreen_keystroke (priv->rules, active);
+
+  if (keystroke)
+  {
+    guint keysym = 0;
+    EggVirtualModifierType modifiers = 0;
+
+    if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
+    {
+      guint mods = 0;
+
+      if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
+        mods |= FAKEKEYMOD_SHIFT;
+      if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
+        mods |= FAKEKEYMOD_CONTROL;
+      if (modifiers & EGG_VIRTUAL_ALT_MASK)
+        mods |= FAKEKEYMOD_ALT;
+      if (modifiers & EGG_VIRTUAL_META_MASK)
+        mods |= FAKEKEYMOD_META;
+
+      g_debug ("Sending fullscreen special event: %s = %d %d",
+               keystroke, keysym, mods);
+      fakekey_press_keysym (priv->fk, keysym, mods);
+      fakekey_release (priv->fk);
+
+      return FALSE;
+     }
+  }
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Sending un-fullscreen F11 event");
+    fakekey_press_keysym (priv->fk, XK_F11, 0);
+    fakekey_release (priv->fk);
+  }
+
+  sleep (STATE_CHANGED_SLEEP);
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    g_debug ("Forcing un-fullscreen wnck event");
+    wnck_window_set_fullscreen (active, FALSE);
+  }
+
+  return FALSE;
+}
+
+static void
+unfullscreen (MaximusBind *bind, WnckWindow *window)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  g_timeout_add (KEY_RELEASE_TIMEOUT, (GSourceFunc)real_unfullscreen, bind);
+}
+
+static void
+on_binding_activated (gchar *keystring, MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  WnckWindow *active;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  active = wnck_screen_get_active_window (priv->screen);
+
+  if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
+    return;
+
+  if (wnck_window_is_fullscreen (active))
+  {
+    unfullscreen (bind, active);
+  }
+  else
+  {
+    fullscreen (bind, active);
+  }
+}
+
+/* Callbacks */
+static gboolean
+binding_is_valid (const gchar *binding)
+{
+  gboolean retval = TRUE;
+
+  if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
+    retval = FALSE;
+
+  return retval;
+}
+
+static void
+on_binding_changed (GSettings      *settings,
+                    gchar          *key,
+                    MaximusBind    *bind)
+{
+  MaximusBindPrivate *priv;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_unbind (priv->binding,
+                             (TomboyBindkeyHandler)on_binding_changed);
+  g_free (priv->binding);
+
+  priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  g_print ("Binding changed: %s\n", priv->binding);
+}
+
+/* GObject stuff */
+static void
+create_rule (MaximusBind *bind, const gchar *filename)
+{
+#define RULE_GROUP "Fullscreening"
+#define RULE_WMCLASS "WMClass"
+#define RULE_FULLSCREEN "Fullscreen"
+#define RULE_UNFULLSCREEN "Unfullscreen"
+  MaximusBindPrivate *priv;
+  GKeyFile *file;
+  GError *error = NULL;
+  MaximusRule *rule;
+
+  priv = bind->priv;
+
+  file = g_key_file_new ();
+  g_key_file_load_from_file (file, filename, 0, &error);
+  if (error)
+  {
+    g_warning ("Unable to load %s: %s\n", filename, error->message);
+    g_error_free (error);
+    g_key_file_free (file);
+    return;
+  }
+
+  rule = g_slice_new0 (MaximusRule);
+
+  rule->wm_class = g_key_file_get_string (file,
+                                          RULE_GROUP, RULE_WMCLASS,
+                                          NULL);
+  rule->fullscreen = g_key_file_get_string (file,
+                                            RULE_GROUP, RULE_FULLSCREEN,
+                                            NULL);
+  rule->unfullscreen = g_key_file_get_string (file,
+                                              RULE_GROUP, RULE_UNFULLSCREEN,
+                                              NULL);
+  if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
+  {
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+    g_slice_free (MaximusRule, rule);
+
+    g_warning ("Unable to load %s, missing strings", filename);
+  }
+  else
+    priv->rules = g_list_append (priv->rules, rule);
+
+  g_key_file_free (file);
+}
+
+static void
+load_rules (MaximusBind *bind, const gchar *path)
+{
+  MaximusBindPrivate UNUSED_VARIABLE *priv;
+  GDir *dir;
+  const gchar *name;
+
+  priv = bind->priv;<--- Variable 'priv' is assigned a value that is never used.
+
+  dir = g_dir_open (path, 0, NULL);
+
+  if (!dir)
+    return;
+
+  while ((name = g_dir_read_name (dir)))
+  {
+    gchar *filename;
+
+    filename= g_build_filename (path, name, NULL);
+
+    create_rule (bind, filename);
+
+    g_free (filename);
+  }
+
+  g_dir_close (dir);
+}
+
+static void
+maximus_bind_finalize (GObject *obj)
+{
+  MaximusBind *bind = MAXIMUS_BIND (obj);
+  MaximusBindPrivate *priv;
+  GList *r;
+
+  g_return_if_fail (MAXIMUS_IS_BIND (bind));
+  priv = bind->priv;
+
+  for (r = priv->rules; r; r = r->next)
+  {
+    MaximusRule *rule = r->data;
+
+    g_free (rule->wm_class);
+    g_free (rule->fullscreen);
+    g_free (rule->unfullscreen);
+
+    g_slice_free (MaximusRule, rule);
+  }
+  g_free (priv->binding);
+
+  G_OBJECT_CLASS (maximus_bind_parent_class)->finalize (obj);
+}
+
+static void
+maximus_bind_class_init (MaximusBindClass *klass)
+{
+  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
+
+  obj_class->finalize = maximus_bind_finalize;
+}
+
+static void
+maximus_bind_init (MaximusBind *bind)
+{
+  MaximusBindPrivate *priv;
+  GdkDisplay *display = gdk_display_get_default ();
+  WnckScreen *screen;
+
+  priv = bind->priv = maximus_bind_get_instance_private (bind);
+
+  priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display));
+  priv->screen = screen = wnck_screen_get_default ();<--- Variable 'screen' is assigned a value that is never used.
+  priv->rules = NULL;
+  priv->settings = g_settings_new (BIND_SCHEMA);
+
+  tomboy_keybinder_init ();
+
+  g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,
+                    G_CALLBACK (on_binding_changed), bind);
+
+  priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS);
+
+  if (binding_is_valid (priv->binding))
+    tomboy_keybinder_bind (priv->binding,
+                           (TomboyBindkeyHandler)on_binding_activated,
+                           bind);
+
+  load_rules (bind, SYSRULESDIR);
+}
+
+MaximusBind *
+maximus_bind_get_default (void)
+
+{
+  static MaximusBind *bind = NULL;
+
+  if (!bind)
+    bind = g_object_new (MAXIMUS_TYPE_BIND,
+                       NULL);
+
+  return bind;
+}
+
+ +
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/4.html b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/4.html new file mode 100644 index 0000000..b54f847 --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/4.html @@ -0,0 +1,915 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
/* tomboykeybinder.c
+ * Copyright (C) 2008 Novell
+ * Copyright (C) 2012-2021 MATE Developers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
+ */
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "eggaccelerators.h"
+#include "tomboykeybinder.h"
+
+/* Uncomment the next line to print a debug trace. */
+/* #define DEBUG */
+
+#ifdef DEBUG
+#  define TRACE(x) x
+#else
+#  define TRACE(x) do {} while (FALSE);
+#endif
+
+typedef struct _Binding {
+	TomboyBindkeyHandler  handler;
+	gpointer              user_data;
+	char                 *keystring;
+	uint                  keycode;
+	uint                  modifiers;
+} Binding;
+
+static GSList *bindings = NULL;
+static guint32 last_event_time = 0;
+static gboolean processing_event = FALSE;
+
+static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
+
+static void
+lookup_ignorable_modifiers (GdkKeymap *keymap)
+{
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_LOCK_MASK,
+					      &caps_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_NUM_LOCK_MASK,
+					      &num_lock_mask);
+
+	egg_keymap_resolve_virtual_modifiers (keymap, 
+					      EGG_VIRTUAL_SCROLL_LOCK_MASK,
+					      &scroll_lock_mask);
+}
+
+static void
+grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin, 
+				      Binding   *binding,
+				      gboolean   grab)
+{
+	guint mod_masks [] = {
+		0, /* modifier only */
+		num_lock_mask,
+		caps_lock_mask,
+		scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask,
+		num_lock_mask  | scroll_lock_mask,
+		caps_lock_mask | scroll_lock_mask,
+		num_lock_mask  | caps_lock_mask | scroll_lock_mask,
+	};
+	int i;
+
+	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
+		if (grab) {
+			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin), 
+				  binding->keycode, 
+				  binding->modifiers | mod_masks [i], 
+				  GDK_WINDOW_XID (rootwin), 
+				  False, 
+				  GrabModeAsync,
+				  GrabModeAsync);
+		} else {
+			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
+				    binding->keycode,
+				    binding->modifiers | mod_masks [i], 
+				    GDK_WINDOW_XID (rootwin));
+		}
+	}
+}
+
+static gboolean 
+do_grab_key (Binding *binding)
+{
+	GdkDisplay *gdk_display = gdk_display_get_default ();
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display);
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	EggVirtualModifierType virtual_mods = 0;
+	guint keysym = 0;
+
+	if (keymap == NULL || rootwin == NULL)
+		return FALSE;
+
+	if (!egg_accelerator_parse_virtual (binding->keystring, 
+					    &keysym, 
+					    &virtual_mods))
+		return FALSE;
+
+	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
+
+	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin), 
+					     keysym);
+	if (binding->keycode == 0)
+		return FALSE;
+
+	TRACE (g_print ("Got keycode %d\n", binding->keycode));
+
+	egg_keymap_resolve_virtual_modifiers (keymap,
+					      virtual_mods,
+					      &binding->modifiers);
+
+	TRACE (g_print ("Got modmask %d\n", binding->modifiers));
+
+	gdk_x11_display_error_trap_push (gdk_display);
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      TRUE /* grab */);
+
+	gdk_display_flush (gdk_display);
+
+	if (gdk_x11_display_error_trap_pop (gdk_display)) {
+	   g_warning ("Binding '%s' failed!\n", binding->keystring);
+	   return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean 
+do_ungrab_key (Binding *binding)
+{
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
+
+	grab_ungrab_with_ignorable_modifiers (rootwin, 
+					      binding, 
+					      FALSE /* ungrab */);
+
+	return TRUE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+	GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
+	XEvent *xevent = (XEvent *) gdk_xevent;
+	guint event_mods;
+	GSList *iter;
+
+	TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
+
+	switch (xevent->type) {
+	case KeyPress:
+		TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n", 
+				xevent->xkey.keycode, 
+				xevent->xkey.state));
+
+		/* 
+		 * Set the last event time for use when showing
+		 * windows to avoid anti-focus-stealing code.
+		 */
+		processing_event = TRUE;
+		last_event_time = xevent->xkey.time;
+
+		event_mods = xevent->xkey.state & ~(num_lock_mask  | 
+						    caps_lock_mask | 
+						    scroll_lock_mask);
+
+		for (iter = bindings; iter != NULL; iter = iter->next) {
+			Binding *binding = (Binding *) iter->data;
+						       
+			if (binding->keycode == xevent->xkey.keycode &&
+			    binding->modifiers == event_mods) {
+
+				TRACE (g_print ("Calling handler for '%s'...\n", 
+						binding->keystring));
+
+				(binding->handler) (binding->keystring, 
+						    binding->user_data);
+			}
+		}
+
+		processing_event = FALSE;
+		break;
+	case KeyRelease:
+		TRACE (g_print ("Got KeyRelease! \n"));
+		break;
+	}
+
+	return return_val;
+}
+
+static void 
+keymap_changed (GdkKeymap *map)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GSList *iter;
+
+	TRACE (g_print ("Keymap changed! Regrabbing keys..."));
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_ungrab_key (binding);
+	}
+
+	lookup_ignorable_modifiers (keymap);
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+		do_grab_key (binding);
+	}
+}
+
+void 
+tomboy_keybinder_init (void)
+{
+	GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+	GdkWindow *rootwin = gdk_get_default_root_window ();
+
+	lookup_ignorable_modifiers (keymap);
+
+	gdk_window_add_filter (rootwin, 
+			       filter_func, 
+			       NULL);
+
+	g_signal_connect (keymap, 
+			  "keys_changed",
+			  G_CALLBACK (keymap_changed),
+			  NULL);
+}
+
+void 
+tomboy_keybinder_bind (const char           *keystring,
+		       TomboyBindkeyHandler  handler,
+		       gpointer              user_data)
+{
+	Binding *binding;
+	gboolean success;
+
+	binding = g_new0 (Binding, 1);
+	binding->keystring = g_strdup (keystring);
+	binding->handler = handler;
+	binding->user_data = user_data;
+
+	/* Sets the binding's keycode and modifiers */
+	success = do_grab_key (binding);
+
+	if (success) {
+		bindings = g_slist_prepend (bindings, binding);
+	} else {
+		g_free (binding->keystring);
+		g_free (binding);
+	}
+}
+
+void
+tomboy_keybinder_unbind (const char           *keystring, 
+			 TomboyBindkeyHandler  handler)<--- Parameter 'handler' can be declared as pointer to const
+{
+	GSList *iter;
+
+	for (iter = bindings; iter != NULL; iter = iter->next) {
+		Binding *binding = (Binding *) iter->data;
+
+		if (strcmp (keystring, binding->keystring) != 0 ||
+		    handler != binding->handler) 
+			continue;
+
+		do_ungrab_key (binding);
+
+		bindings = g_slist_remove (bindings, binding);
+
+		g_free (binding->keystring);
+		g_free (binding);
+		break;
+	}
+}
+
+/* 
+ * From eggcellrenderkeys.c.
+ */
+gboolean
+tomboy_keybinder_is_modifier (guint keycode)
+{
+	gint i;
+	gint map_size;
+	XModifierKeymap *mod_keymap;
+	gboolean retval = FALSE;
+
+	mod_keymap = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+	map_size = 8 * mod_keymap->max_keypermod;
+
+	i = 0;
+	while (i < map_size) {
+		if (keycode == mod_keymap->modifiermap[i]) {
+			retval = TRUE;
+			break;
+		}
+		++i;
+	}
+
+	XFreeModifiermap (mod_keymap);
+
+	return retval;
+}
+
+guint32
+tomboy_keybinder_get_current_event_time (void)
+{
+	if (processing_event) 
+		return last_event_time;
+	else
+		return GDK_CURRENT_TIME;
+}
+
+ +
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/index.html b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/index.html new file mode 100644 index 0000000..18b869d --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/index.html @@ -0,0 +1,217 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeSysteminformationCppcheck cannot find all the include files (use --check-config for details)
maximus/eggaccelerators.c
322duplicateExpression398styleSame expression on both sides of '-='.
maximus/main.c
96unreadVariable563styleVariable 'app' is assigned a value that is never used.
maximus/maximus-app.c
124knownConditionTrueFalse571styleCondition 'data' is always true
maximus/maximus-bind.c
147unreadVariable563styleVariable 'display' is assigned a value that is never used.
206unreadVariable563styleVariable 'priv' is assigned a value that is never used.
221unreadVariable563styleVariable 'display' is assigned a value that is never used.
279unreadVariable563styleVariable 'priv' is assigned a value that is never used.
403unreadVariable563styleVariable 'priv' is assigned a value that is never used.
467unreadVariable563styleVariable 'screen' is assigned a value that is never used.
maximus/tomboykeybinder.c
282constParameter398styleParameter 'handler' can be declared as pointer to const
+
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/stats.html b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/stats.html new file mode 100644 index 0000000..e04c5c7 --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/stats.html @@ -0,0 +1,171 @@ + + + + + + Cppcheck - HTML report - mate-netbook + + + + + +
+ + + +
+

Top 10 files for style severity, total findings: 10
+   6  maximus/maximus-bind.c
+   1  maximus/tomboykeybinder.c
+   1  maximus/maximus-app.c
+   1  maximus/main.c
+   1  maximus/eggaccelerators.c
+

+ +
+ +
+ + diff --git a/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/style.css b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/style.css new file mode 100644 index 0000000..3897bfa --- /dev/null +++ b/2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/style.css @@ -0,0 +1,177 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + height: 100%; + margin: 0; +} + +#wrapper { + position: fixed; + height: 100vh; + width: 100vw; + display: grid; + grid-template-rows: fit-content(8rem) auto fit-content(8rem); + grid-template-columns: fit-content(25%) 1fr; + grid-template-areas: + "header header" + "menu content" + "footer footer"; +} + +h1 { + margin: 0 0 8px -2px; + font-size: 175%; +} + +.header { + padding: 0 0 5px 15px; + grid-area: header; + border-bottom: thin solid #aaa; +} + +.footer { + grid-area: footer; + border-top: thin solid #aaa; + font-size: 85%; + +} + +.footer > p { + margin: 4px; +} + +#menu, +#menu_index { + grid-area: menu; + text-align: left; + overflow: auto; + padding: 0 23px 15px 15px; + border-right: thin solid #aaa; + min-width: 200px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; +} + +#content, +#content_index { + grid-area: content; + padding: 0px 5px 15px 15px; + overflow: auto; +} + +label { + white-space: nowrap; +} + +label.checkBtn.disabled { + color: #606060; + background: #e0e0e0; + font-style: italic; +} + +label.checkBtn, input[type="text"] { + border: 1px solid grey; + border-radius: 4px; + box-shadow: 1px 1px inset; + padding: 1px 5px; +} + +label.checkBtn { + white-space: nowrap; + background: #ccddff; +} + +label.unchecked { + background: #eff8ff; + box-shadow: 1px 1px 1px; +} + +label.checkBtn:hover, label.unchecked:hover{ + box-shadow: 0 0 2px; +} + +label.disabled:hover { + box-shadow: 1px 1px inset; +} + +label.checkBtn > input { + display:none; +} + +.summaryTable { + width: 100%; +} + +table.summaryTable td { padding: 0 5px 0 5px; } + +.statHeader, .severityHeader { + font-weight: bold; +} + +.warning { + background-color: #ffffa7; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.id-filtered, .severity-filtered, .file-filtered, .tool-filtered, .text-filtered { + visibility: collapse; +} diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..6694124 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +mate-netbook.mate-desktop.dev diff --git a/index.html b/index.html new file mode 100644 index 0000000..4af6f45 --- /dev/null +++ b/index.html @@ -0,0 +1,46 @@ + + + + + mate-netbook Code Analyzer results + + +

+ mate-desktop/mate-netbook Static analyzer results +

+ GitHub + Build Status +
+Commit: 6b49a8c0d49deae5d079a342b4843f8dcb856410
+Compare:
+Branch: meson
+Time: 2023-07-21 03:09:03+00:00
+Messages:
+
+Add meson compilation support
+
+
+ + + -- cgit v1.2.1