❌

Normal view

SpamSieve 3.3.1

15 July 2026 at 19:53

SpamSieve 3.3.1 is an update of my Mac e-mail spam filter that improves the filtering accuracy and includes various optimizations, fixes, and updates for macOS 27. Some interesting engineering issues were:

  • I’m still supporting macOS 10.13, but the app can now build with the macOS 12 deployment target in preparation for Xcode 27. The way Swift handles calling deprecated APIs remains annoying. You need workarounds like protocols to suppress a warning in a particular region of code. Often, I am updating to a newer API, but I want to continue using the old one on earlier versions of macOS. Right now I am heavily testing on macOS 26, so I would like to only deploy the new code there. Sometimes the initial versions of APIs are buggy, and I don’t want to have to retest every feature on every version. But Swift doesn’t like me to gate the calls to macOS 26 and later if the new API was actually introduced in, say, macOS 11.

  • The most risky update was probably switching to the Swift API for Scanner. This is tricky because the current scan position changes from being based on UTF-16 indexes to String.Index. And in some cases my code was intentionally scanning into the middle of a combining character. I was really glad to have extensive tests here.

  • Recent versions of Tahoe introduced a Core Data bug that broke save recovery (when invalid Unicode can’t be written to the database and we have to fix it up first). When the error comes in, SpamSieve looks under the NSDetailedErrorsKey key, but the value of this key is "NSDetailedErrorsKey" while the actual error info is under the key "NSDetailedErrors".

  • Database corruption combined with a Core Data bug and two Swift behaviors were causing crashes. The root problem, I think, is that in this situation Core Data neglects to set the error pointer for -[NSManagedObjectContext countForFetchRequest:error:]. Normally, Swift would detect this and throw a generic nilError. However, this method signals errors by returning NSNotFound instead of nil. It’s annotated as swift_error(nonnull_error), which I think means that Swift doesn’t even look at the return value, only the (unset) error. So my code was receiving NSNotFound on the non-error path, treating it as a real count, and doing some math with it, which (by default in Swift) leads to a crash if there’s overflow. Now my code checks for NSNotFound and uses Int.addingReportingOverflow().

  • I reimplemented Core Data batch fetching because of two problems with the fetchBatchSize option. First, it logs spurious errors when fetching from multiple stores at once. Second, it leads to high memory use. It will load objects in batches, but it never releases the earlier batches. You can manually refault objects that you no longer need, but it will still hold onto the full object shells, which can add up. My implementation only holds onto IDs, and it can fetch the IDs using a different context than the objects to push more work to background threads.

  • I’m now using String.makeContiguousUTF8() in various places to avoid slow iteration of bridged strings.

  • There was a regression where some menu code could crash on macOS 10.13. -[NSMenu setItemArray:] is only available on macOS 10.14 and later, whereas the getter is always available. With old Objective-C, the two methods could be annotated with separate availabilities. The Objective-C property syntax doesn’t allow this, so there’s no way for the compiler to flag calls where the setter is missing.

  • The AppleScript support works much better with large data sets. The key, I think, is to never return an array to Cocoa for a scripting property/element. First, if you give it a lazy array it will sometimes try to access all the elements even if it only needs a few. And, second, AppleScript will run out of memory if the array is too large. By using indexed accessors, you can maintain laziness and only convert one object to a descriptor at a time. By caching a batch-fetching collection, you can limit the number of fetches and respond quickly when AppleScript requests individual objects.

Previously:

Searching Time Machine Backups and Versions

9 July 2026 at 19:38

Howard Oakley:

Spotlight doesn’t currently appear able to search Time Machine backups reliably, at least not in Sequoia or Tahoe, although this may not be universal.

[…]

If I now step back through my backups to reach one that I know contains that file, I can restore it. But if I type anything into the search field, nothing is found. If I change the scope of the search to that backup, the window title changes but its contents remain blank, and there isn’t even a busy spinner to indicate a search is in progress.

[…]

As I can’t disable Spotlight indexing on that volume without macOS telling me that it’s required to be indexed by Spotlight, neither can I force that volume to be reindexed.

[…]

My conclusion is that using Spotlight to search Time Machine backups no longer works, and the instructions given by Apple are also broken.

That has been my experience, too. As I see it, there are four separate problems:

  1. I want to be able to search all my backup snapshots, because I don’t know which one might contain the file I want to restore. Time Machine only lets you search one at a time.
  2. Searching an individual snapshot doesn’t actually work.
  3. Spotlight indexing is invasive, using lots of CPU time, and with spinning hard drives causes wear and tear and creates lots of noise. If search doesn’t work anyway, I’d like to turn it off, but macOS won’t let me.
  4. If the problem is with the index, there’s no way to reset it without deleting your backup.

Howard Oakley:

Unfortunately, all those saved versions in the version database fall outside the scope of Spotlight indexing, and Spotlight search can’t look inside any of the old versions saved in a volume’s version database. Surprisingly, the version browser doesn’t offer any search facilities either, as that’s presumably another feature intended for a future that never came.

[…]

One way around this is to save each document version as a separate file, allow Spotlight to extract their contents and add those to its indexes for that volume, then to search those files. This is quick and simple using my free utility Versatility.

Previously:

WebKit Always Enables the Copy Menu Item in Every App

25 June 2026 at 18:26

John Gruber (Mastodon):

In most Mac apps, since the dawn of time, if there is nothing selected to be copied, the Edit → Copy (and Cut) commands are disabled. If you invoke the ⌘C shortcut while the Copy command is disabled, you hear an alert sound, letting you know that whatever you thought you were copying could not be copied because it wasn’t selected. That beep is useful context. This is proper behavior for all menu items — if they’re not available to do something, they should be disabled, and invoking a disabled menu item keyboard shortcut should beep. In any app that uses WebKit, since early in 2025, the Copy command is always enabled when a WebKit view has focus — but if nothing is selected, you get useless clipboard data that can’t actually be pasted anywhere. (And whatever was on your clipboard is now gone, or pushed back if you use a clipboard history utility.)

Jeff Johnson:

I decided to file a bug report on behalf of Gruber: Copy main menu item is enabled with no selection in the web page. I subsequently learned that the first appearance of the bug was January 2025 in the WebKit source code, February 2025 in Safari Technology Preview 213, and March 2025 in Safari 18.4, as a result of attempting to fix another bug, document.execCommand("copy") only triggers if there is a selection, reported in 2016, nine years prior!

[…]

Sadly, my bug report was closed with the resolution “won’t fix.” The refusal appears to be based on a misunderstanding[…]

Jeff Johnson:

LOL that was fast.

Sometimes Apple is hilarious.

Previously:

Update (2026-07-30): Saron Yitbarek (via Jeff Johnson):

Fixed the Edit menu’s Copy item being incorrectly enabled when there was no selection in the web page.

Billing Software Error Sends Billion-Dollar AWS Estimates

By: BeauHD
17 July 2026 at 22:00
AWS says a billing software bug caused some customers to see wildly inflated estimated charges, including reports of accounts showing bills in the billions or even trillions of dollars. The Register reports: An open issue on the AWS Health Dashboard (archived copy at the time of writing) popped up at 1:33 am Pacific time on Friday informing users that Cost Explorer was "reflecting inaccurate estimated billing data." As of writing, the issue is still unresolved despite AWS trying several different things to get it fixed. The company apparently identified the root cause within an hour and a half of beginning its investigation, only describing it as "an issue with unit pricing within the estimated billing computation subsystem." AWS followed up by pausing estimated bill updates, saying customers would continue to see the inflated figures already displayed, but that those estimates would not increase further. "The displayed billing estimates do not reflect actual usage and charges," AWS explained, noting that customers don't need to take any action, like, we imagine, flooding the help portal with tickets telling them what they already know, for instance. "Once the issue has been mitigated, we expect full resolution to take multiple hours as we work through recomputing the estimated billing data," AWS added. After we first published this article, Amazon updated the issue page to indicate that it had identified the root cause and mitigated the underlying issue. The company says that it's begun backfilling data in the Cost Management Console to correct billing numbers, and that all customers should see corrected amounts by Saturday, July 18 at noon pacific time.

Read more of this story at Slashdot.

Google Told Researcher 'Nice Catch!' Then Denied Bug Bounty For Flaw It Still Hasn't Fixed

By: BeauHD
18 June 2026 at 18:00
Security researcher Justin O'Leary says Google initially accepted his Config Connector privilege-escalation report as a high-priority, high-severity bug, then denied a bounty by declaring the behavior "working as intended." According to The Register, a Google rep initially praised O'Leary's report with a "Nice catch!" before the cloud giant reversed course, declaring that no vulnerability existed and therefore no fix or reward was warranted. "The bug report, however, is still marked high-priority and accepted," the publication notes. The alleged flaw, dubbed ConfigConfusion, could let a Kubernetes namespace user exploit an overprivileged service account to become a GCP organization owner with only a few lines of YAML and little apparent audit visibility. O'Leary details the incident in a blog post. The Register reports: According to O'Leary, Config Connector doesn't perform an authorization check, and this allows any Config Connector service account with org-level permissions to bypass Identity and Access Management (IAM) authorization and gain the highest level of control (roles/owner) to an entire GCP Organization -- the root node of all of a company's resources within Google Cloud. On March 27, a Google security engineer accepted O'Leary's report and told him: "Nice catch!" The employee said that they filed a bug based on O'Leary's report with the relevant product team and assured him the Chocolate Factory's security squad would work with relevant Google Cloud people to fix the flaw. "We'll work with the product team to ensure this issue is address. We'll let you know when the issue was fixed," the engineer said. "In the meantime, review the payment option selected in your bughunters.google.com profile." Google assigned the bug P1 priority and S1 severity, signifying a flaw worthy of urgent repair because it affects a large percentage of users and can disrupt core organizational functions. "I figured that was the end of that," O'Leary said in a phone interview with The Register. Eleven days later, on April 7, he received a new message from a Google Security Bot reversing the earlier decision. The Reg viewed the email, and O'Leary included a screenshot in his Thursday writeup. The message said that the Cloud Vulnerability Reward Program panel decided that the "security impact of this issue does not meet the criteria to qualify for a reward." After reviewing the bug report, Google determined the software "is working as intended," the message continued. It also noted that the program's decision not to pay a bounty "does not mean that the product team won't fix the issue." Nearly three months later, the case remains P1/S1 with the status "in progress (accepted)." Google hasn't assigned a CVE or issued a fix. O'Leary didn't receive any reward for his research. [...] "This is a pattern," O'Leary told [The Register]. "This is just how these trillion-dollar companies deal with people like me. In my day job, we use GKE, and it's incredibly frustrating on my end, when I find a critical vulnerability in the system that's being widely used, and I can't even get the vendor to patch their own stuff." A Google spokesperson told The Register: "The issue reported does not qualify for a reward because the GCP IAM authorization bypass is only exploitable if an attacker has access to a Config Connector Service Account that's been granted the Organization Admin role by the organization (i.e., it is privileged). Additionally, an attacker would first need to gain entry to an organization's environment (e.g., an exposed container) in order to leverage the privileged Config Connector instance and execute commands with administrative authority, such as the IAM bypass. Granting this level of access to the Config Connector Service Account goes against Google Cloud's publicly shared best practices and the principle of least privilege."

Read more of this story at Slashdot.

❌