{"id":901,"date":"2020-12-17T18:56:43","date_gmt":"2020-12-17T23:56:43","guid":{"rendered":"https:\/\/www.brunerd.com\/blog\/?p=901"},"modified":"2020-12-17T23:53:34","modified_gmt":"2020-12-18T04:53:34","slug":"jpt-is-unphased-by-macoss-malformed-json","status":"publish","type":"post","link":"https:\/\/www.brunerd.com\/blog\/2020\/12\/17\/jpt-is-unphased-by-macoss-malformed-json\/","title":{"rendered":"jpt is unphased by macOS&#8217;s malformed JSON"},"content":{"rendered":"\n<p>A funny thing happened on the way to writing a new blog entry. Instead of finding an example JSON file that ships with macOS, I stumbled upon a <a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/brunerd\/e3b3f223ff4041f153839336ff75c965\" target=\"_blank\">slow creep<\/a> of malformed JSON files that started in OS X El Capitan and continues into Big Sur. While I can&#8217;t do much about deviant JSON files in macOS, I <em>can<\/em> control how <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\">jpt<\/a> handles them. So like any good Teachable Moment\u2122 and life lesson, I&#8217;ve turned lemons into lemonade and out of challenge comes innovation: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\/releases\/tag\/v0.9.6\" target=\"_blank\">jpt v0.9.6<\/a> is now nonplussed by these uncouth JSON files, with their comments and trailing commas. Like water off ducks back, jpt keeps on keepin&#8217; on, unphased.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Finding the Misfits<\/h4>\n\n\n\n<p>To find these misfits I wrote made a script <strong><a href=\"https:\/\/gist.github.com\/brunerd\/fc2507a3e138e615d84e8f322e6d7c3b\">jsonParsingReportCSV-macOS<\/a><\/strong>. This will attempt to parse the JSON it finds using the json_pp binary that ships from Apple, the results are output as CSV and you can then easily sort it to spot troublemakers.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jsonReport-Example.png\"><img loading=\"lazy\" decoding=\"async\" width=\"943\" height=\"285\" src=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jsonReport-Example.png\" alt=\"\" class=\"wp-image-904\" srcset=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jsonReport-Example.png 943w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jsonReport-Example-300x91.png 300w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jsonReport-Example-768x232.png 768w\" sizes=\"auto, (max-width: 943px) 100vw, 943px\" \/><\/a><\/figure>\n\n\n\n<p>I&#8217;ve uploaded a couple annotated version of those searches along with the kind of deviation they exhibit: <strong><a href=\"https:\/\/gist.github.com\/brunerd\/951e1d1be59ef99159bdf58907b13f7f\">Malformed-macOS-10.15.csv<\/a><\/strong> and <a href=\"https:\/\/gist.github.com\/brunerd\/b84764043ba3afec82ca9ee7c0735070\"><strong>Malformed-macOS-11.1.csv<\/strong><\/a><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">What&#8217;s their damage, man?<\/h4>\n\n\n\n<p>The two most prevalent kinds of JSON malformation I found in macOS were: trailing commas and comments. Trailing commas meaning the last item in an array or object should not have a comma after it. While <em>Javascript<\/em> <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Trailing_commas\" target=\"_blank\">has always allowed trailing commas<\/a> in array literals and later in object literals (ES5), then in function parameters (ES2017), JSON has <em>never<\/em> allowed trailing commas nor comments. Neither are in the JSON spec (<a rel=\"noreferrer noopener\" href=\"https:\/\/tools.ietf.org\/html\/rfc8259\" target=\"_blank\">RFC8259<\/a>).<\/p>\n\n\n\n<p>The biggest group of offenders were the USD <a rel=\"noreferrer noopener\" href=\"https:\/\/graphics.pixar.com\/usd\/docs\/api\/_usd__page__generating_schemas.html\" target=\"_blank\">generated<\/a> JSONs within USDKit (a private framework) and <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/documentation\/modelio\" target=\"_blank\">Model I\/O<\/a>. USD is interesting because of it&#8217;s lineage and purpose: It&#8217;s Pixar&#8217;s open source software for combining multiple 3D elements within a common scene. Or as <a rel=\"noreferrer noopener\" href=\"https:\/\/graphics.pixar.com\/usd\/docs\/Introduction-to-USD.html\" target=\"_blank\">Pixar&#8217;s page put it<\/a>: &#8220;<em>Universal Scene Description (USD) is the first publicly available software that addresses the need to robustly and scalably interchange and augment arbitrary 3D scenes that may be&nbsp;composed&nbsp;from many elemental assets.<\/em>&#8221; Keep an <em>eye<\/em> on this framework \ud83d\udd76<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">JSON Lines (<a href=\"https:\/\/www.youtube.com\/watch?v=7bCdrDhUjPo\" target=\"_blank\" rel=\"noreferrer noopener\">Don&#8217;t Do It<\/a>)<\/h4>\n\n\n\n<p>An outlier in the mix is <a rel=\"noreferrer noopener\" href=\"\/\/\/System\/Library\/PrivateFrameworks\/CoreAnalytics.framework\/Versions\/A\/Resources\/defaultConfig.json\" target=\"_blank\">defaultConfig.json<\/a> within CoreAnalytics.framework, it is what some call &#8220;<a rel=\"noreferrer noopener\" href=\"https:\/\/jsonlines.org\" target=\"_blank\">JSON Lines<\/a>&#8221; or &#8220;concatenated JSON&#8221;, where each line is its own a JSON value or object. While doing some research on JSON Lines I came upon an intriguing comment in <a rel=\"noreferrer noopener\" href=\"https:\/\/news.ycombinator.com\/item?id=21901539\" target=\"_blank\">this post<\/a> by <a rel=\"noreferrer noopener\" href=\"https:\/\/news.ycombinator.com\/user?id=rurban\" target=\"_blank\">rurban<\/a>: <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>&#8220;The delimiters don&#8217;t get in the way, they protect you from MITM and other attacks. It&#8217;s a security feature, not a bug.&#8221; <\/p><cite>Reini Urban on JSON vs. &#8220;concatenated JSON&#8221;<\/cite><\/blockquote>\n\n\n\n<p>Taking a look at Reini&#8217;s <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/rurban\" target=\"_blank\">GitHub<\/a> and the level of his work, I&#8217;m going to give his statement some credence. To that end, I really didn&#8217;t want to add another output mode nor change query behavior to accommodate JSON Lines. My current compromise is to simply to attempt conversion of a JSON Lines file into an array: tack on commas and ensconce in square brackets. It Just Works\u2122 if every line is truly a self contained JSON object. If you want to be made <em>aware<\/em> of this, use the -c option so jpt it will &#8220;complain&#8221; on stderr and exit with code 1.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The Rabbit Hole of CoreAnalytics<\/h4>\n\n\n\n<p>Within the <strong>CoreAnalytics<\/strong> private framework is <a rel=\"noreferrer noopener\" href=\"\/\/\/System\/Library\/PrivateFrameworks\/CoreAnalytics.framework\/Versions\/A\/Resources\/defaultConfig.json\" target=\"_blank\">defaultConfig.json<\/a>, it is a collection of 4019  objects currently that describe the events and actions Apple is interested in collecting usage information on. They want to know if you&#8217;re actually using all those new features in CarPlay, Reminders, Photos, eGPU App usage, etc&#8230; If you want to see all the key names try this: <code>jpt $..addTransform.name \/System\/Library\/PrivateFrameworks\/CoreAnalytics.framework\/Versions\/A\/Resources\/defaultConfig.json&nbsp;<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/CoreAnalytics.png\"><img loading=\"lazy\" decoding=\"async\" width=\"630\" height=\"456\" src=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/CoreAnalytics.png\" alt=\"\" class=\"wp-image-910\" srcset=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/CoreAnalytics.png 630w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/CoreAnalytics-300x217.png 300w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><figcaption>Do you <em>actually<\/em> use this stuff? Apple wants to know if it&#8217;s worth their while&#8230;<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">A Comment on JSON Comments<\/h4>\n\n\n\n<p>Comments in JSON has inspired debate far and wide, <a rel=\"noreferrer noopener\" href=\"http:\/\/web.archive.org\/web\/20100629021329\/http:\/\/blog.getify.com\/2010\/06\/json-comments\/\" target=\"_blank\">this post<\/a> by getify sums it up very nicely: <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>A JSON encoder MUST NOT output comments.&nbsp;<strong>A JSON decoder MAY accept and ignore comments.<\/strong><\/p><cite>Douglas Crockford in some old Yahoo group that even Wayback can&#8217;t find anymore<\/cite><\/blockquote>\n\n\n\n<p>So that&#8217;s just what <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\">jpt<\/a> does now, it will <em>never<\/em> encode comments but it will strip out <span style=\"text-decoration: underline;\">any and all<\/span> comments it recognizes automatically, no switches needed. Which style <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Comment_(computer_programming)\" target=\"_blank\">comments<\/a>? <span style=\"text-decoration: underline;\">All of them<\/span> (or most of them):<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table  class=\" table table-hover\" ><tbody><tr><td>Comment<\/td><td>kind<\/td><td>lineage<\/td><\/tr><tr><td><code># comment<\/code><\/td><td>line<\/td><td>shell, Perl, PHP, Python, R, Ruby, MySQL<\/td><\/tr><tr><td><code>\/\/ comment<\/code><\/td><td>line<\/td><td>C(99), Javascript, Java, Swift<\/td><\/tr><tr><td><code>\/* comment *\/<\/code><\/td><td>block<\/td><td>C, Java, Javascript, Swift<\/td><\/tr><tr><td><code>; comment<\/code><\/td><td>line<\/td><td>assembly language (ASM)<\/td><\/tr><tr><td><code>-- comment<\/code><\/td><td>line<\/td><td>Ada, Applescript, Haskell, Lua, SQL<\/td><\/tr><tr><td><code>&lt;!-- comment --><\/code><\/td><td>block<\/td><td>XML<\/td><\/tr><tr><td><code>*** comment ***<\/code><\/td><td>line<\/td><td>macOS&#8217;s ionodecache.json<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If you need a test file you can use my <strong><a href=\"https:\/\/gist.github.com\/brunerd\/b9d028ec0458830f99ee3451474aac82#file-worstjsonever-json\">worstJSONEver.json<\/a><\/strong>. A most horrible JSON file if there ever was one! jpt soldiers on, use -c to see what it does to clean the input (-i0 for no level indents). It shows the initial parse error and each attempt at recovery.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-worstJSONEver.png\"><img loading=\"lazy\" decoding=\"async\" width=\"489\" height=\"115\" src=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-worstJSONEver.png\" alt=\"\" class=\"wp-image-926\" srcset=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-worstJSONEver.png 489w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-worstJSONEver-300x71.png 300w\" sizes=\"auto, (max-width: 489px) 100vw, 489px\" \/><\/a><\/figure><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Fixing the Misfits<\/h4>\n\n\n\n<p>There is no fixing, there is only acceptance. Since most of these files are in SIP protected areas of macOS so it will take <s>an act of God<\/s>, a well filed bug report, for Apple to correct these in a future update. But they usually only act if there&#8217;s a demonstrable bug, in this case it&#8217;s more of an observation about the condition of the JSON files than a clear issue. If someone is really bothered, they could disable SIP and go in and fix them, however future macOS updates will likely revert these changes. Since I haven&#8217;t tried this, who knows, macOS may get ornery and trip OS integrity protections, rendering your system un-bootable, YMMV \ud83e\udd37\u200d\u2642\ufe0f. The real question is if they impact how macOS works and I&#8217;m guessing they don&#8217;t. The apps and frameworks which use these off-spec JSON file must be doing something to correct the issues before parsing. Rest assured though, if you attempt to parse one of these files with <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\">jpt<\/a> there will be no issues, it Just Works\u2122. However if you would like to know it did something, use <strong>-c<\/strong>  to &#8220;complain&#8221; about comments, commas, JSON Lines, and hard wrapping. It will send those notices to stderr and exit with a status of 1.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-complaining-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"455\" height=\"71\" src=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-complaining-1.png\" alt=\"\" class=\"wp-image-915\" srcset=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-complaining-1.png 455w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/jpt-complaining-1-300x47.png 300w\" sizes=\"auto, (max-width: 455px) 100vw, 455px\" \/><\/a><\/figure><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">jpt: malformed JSON? Bring it on.<\/h4>\n\n\n\n<p>So after all this I don&#8217;t have a good example page for jpt&#8217;s multitude of features and usage (yet) <em>but<\/em> what I do have is a JSON Power Tool with more &#8220;dummy-proof&#8221; features than it did before. I&#8217;ll take that as a win! Check out the <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\/releases\/latest\" target=\"_blank\">latest release<\/a> of <a href=\"https:\/\/github.com\/brunerd\/jpt\">jpt<\/a> at my Github.<\/p>\n\n\n\n<p><em><a href=\"https:\/\/github.com\/brunerd\/jpt\">jpt<\/a> (JSON Power Tool) is a non-compiled tool that can<em> manipulate and query JSON in a variety of ways,<\/em> it runs on macOS (10.4 &#8211; 11.0) PPC\/Intel\/Apple Silicon; Linux with jsc; Windows with Linux subsystem for Windows and jsc. It can be used standalone or embedded within your shell scripts. I hope you find it useful. Thanks for reading!<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A funny thing happened on the way to writing a new blog entry. Instead of finding an example JSON file that ships with macOS, I stumbled upon a slow creep of malformed JSON files that started in OS X El Capitan and continues into Big Sur. While I can&#8217;t do much about deviant JSON files [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,37,4],"tags":[],"class_list":["post-901","post","type-post","status-publish","format-standard","hentry","category-apple","category-jpt","category-os-x"],"_links":{"self":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/901","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/comments?post=901"}],"version-history":[{"count":17,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/901\/revisions"}],"predecessor-version":[{"id":930,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/901\/revisions\/930"}],"wp:attachment":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/media?parent=901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/categories?post=901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/tags?post=901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}