Googling around shows that many other people have had the same problem, but still I have been unable to find a fix or workaround. Everything indicates that these are bugs in, most likely, Apache, perhaps also mod_rewrite.
RewriteEngine on RewriteRule ^(.+)/ category.php?name=$1
<?= $_GET['name'] ?>
This will work fine most of the time, the 'name' arg contains the subdirectory of the folder containing the .htaccess file. But, when you put any of the characters that Windows does not permit in a filename (\ / : * ? " < > |) into the subdirectory of the request, Apache returns a 403 Forbidden. Of course, these characters are URL-encoded. It seems like the problem is that Apache is checking the path to be a valid Windows filename before passing it to mod_rewrite where the subdirectory is rewritten to be a script argument that can accept any properly encoded character.
The other problem I am having, is with plus signs. When rewritten they tend to be decoded twice so that given the previous code examples, if you had a category, "C++", encoded as, "C%2B%2B", it becomes, "C " (spaces), in the script. I'm pretty sure I understand why this happens...mod_rewrite decodes the URL before doing any work with it because you can URL-encode the same data in more than one way. For instance, the character "a" could be represented in the URL literally, or as "%61", and mod_rewrite needs to match either of these. So when I pass a plus sign as %2B to mod_rewrite it decodes it to +, then passes the + to the PHP script as an argument which gets decoded once again to a space. A way for mod_rewrite to fix this would be to provide a flag which re-encodes the replacement string in a rewrite rule. I can work around this in PHP by not using $_GET variables at all, and instead just rewriting all subdirectories of a folder to a handler script which parses the request URI directly. Of course, I would rather not though. And my first problem still prevents me from using special Windows filename characters.
Thanks for your guys' help before hand.