Tuesday, February 28, 2017

Jostens yearbook-making web site does not seem to support Unicode

Today I made a start on my yearbook page (the school dedicates a full page to each graduating senior). The yearbook is authored using Jostens' web app. I immediately noticed when trying to insert a character that falls outside the non-control-ASCII range that the app does not seem to handle such characters at all. As in, it's not possible to put in a non-ASCII character into a text box in any way; the character just doesn't get added. It's not just the one character I tried; the same thing seems to happen for at least CJK ones as well.

I couldn't find a way to make that work, but it's possible I missed something. It would be very nice if Jostens could support non-ASCII.

Monday, February 27, 2017

When Internet Explorer is configured to not allow restoring the previous session

There is a Group Policy option for Internet Explorer to disable restoring the previous session. If that's enabled, the menu item that allows a previously closed window's tabs to be called back up will be grayed out. If you feel really strongly about being able to get your tabs back after closing a window and don't have sufficient privilege to tinker with the part of the Registry that stores the policy settings, you do have a workaround.

If the Internet Explorer process is terminated, recovery information about the session isn't deleted. So, to preserve tabs across a reboot, use Task Manager (or equivalent) to terminate iexplore.exe. Then when you come back up and reopen it, click Restore session at the bottom to bring your arrangement back.

Based on my Super User answer.

Sunday, February 26, 2017

When phpBB blows up with "Char out of allowed range"

A forum user noticed that searching for a certain keyword lead not to a search results page, but an error spew. I reproduced the problem, and the specific error was "Char 0xFFFE out of allowed range" (repeated several times, plus some other notices). Searching the database's posts table for that keyword, I found that one post included some encoding-butchered text, a leftover from the forum migration. Using the post ID I found, I opened the editing page on the forum and replaced the text with the un-butchered version. Sure enough, that fixed it.

I also looked around for other instances of this error and found some other posts on the forum that caused it. Since this forum's encoding was double-misencoded, I couldn't always reverse the corruption, so I consulted the (only once-misencoded) SQL file to get the once-butchered text. Running it through this UTF8 decoder, I put the correct text back with the edit page.

Customizing tab completion in PowerShell

Pressing the Tab key asks PowerShell to autocomplete the command part you're typing. Interestingly, you can override the default function to implement your own tab completion. In PowerShell 5, that function is TabExpansion2; before, it was just TabExpansion.

The easiest way to customize it is to get its original source code and then insert your own logic, delegating to the original code when necessary. You can extract a function's PowerShell code like so:

(Get-Command 'TabExpansion2').ScriptBlock

Once you have your custom version, you probably want to put it in one of your profile scripts so it's automatically loaded and usable.

For example, my Super User answer removes the .exe extension from tab completion suggestions when it's not needed.

Friday, February 24, 2017

CloudFlare leaks: change your passwords

In case you have not yet heard, CloudFlare - which handles the traffic for many, many web sites - had a bug that spewed sensitive data into responses of certain requests. Fortunately, it's over now, but some users' credentials were definitely compromised.

Here is a big list of notable potentially affected sites. Note that not nearly all sites there were affected, and it's not guaranteed that all affected sites are there; it's just a useful resource. I strongly suggest you change your passwords - or, better yet, enable two-factor authentication where possible - on the CloudFlare sites you use.

Further reading:

Thursday, February 23, 2017

Using Shell.Application in PowerShell

If you're translating VBScript to PowerShell, you'll almost certainly run across a CreateObject("Shell.Application") call. The PowerShell equivalent is surprisingly easy, much more convenient than in a compiled .NET language:

New-Object -ComObject 'Shell.Application'

The resulting object's methods are all there as expected and can even be tab-completed.

Other COM objects can be similarly instantiated.

Wednesday, February 22, 2017

Moving the UAC slider all the way down does not completely disable UAC

If you drag the slider in the UAC control panel to the bottom setting, you won't see any more UAC prompts, and you might think the feature is disabled. That's not quite the case. Though any application that requests elevation will get it without your intervention, the applications still have to ask. If, for example, you run the command prompt as normal, you won't be able to perform administrative actions. Rather, you still need to right-click it and choose "run as administrator," at which point you'll get an administrative command window on your screen with no UAC prompt.

Further reading: my Super User answer.

Tuesday, February 21, 2017

Copying text out of (almost) any dialog

Suppose a program throws up a big warning dialog with a whole bunch of text that that you want to save but don't care to fully transcribe. (Office does this sometimes.) And, unlike some system messages, Ctrl+C doesn't copy the message to the clipboard.

If you want to get text out of these applications, you can use the Inspect tool from the Windows SDK. (The only important part here of that bundle is the Windows Software Development Kit component.) The tool gets dropped into here, or a slight permutation thereof:

C:\Program Files (x86)\Windows Kits\10\bin\x64\inspect.exe

Use the Watch Cursor mode (the pointer icon in the toolbar) to select the target object by hovering your mouse over it for a moment. When Inspect's main pane updates, disable that mode to reduce the chance of accidentally deadlocking the tool - which is surprisingly easy - then you'll see a whole bunch of information. In that list you should find some property or another that contains the text, which you can copy as normal.

Based on my Super User answer.

Monday, February 20, 2017

PSThar - All the output streams

People make mistakes and scripts encounter errors, and previously there was no convenient way to get the errors out of a PSThar script. If something bad happened, you'd probably get no output and you'd need to run $error to see what the problem is.

So today, I added a dropdown in the lower left that lets you choose which output you'd like to see in the results pane: normal output, errors, warnings, information, or verbosity. At the completion of a script, the view is automatically moved to the first of those that actually has anything to say.

I also noticed today that entering invalid syntax caused the window to stay as if a script was executing, except that the Stop Script button did nothing. The problem was that syntax errors throw an exception in the Invoke call, which killed the thread that was supposed to compute and report the results. Those exceptions are now caught and handled appropriately.

Sunday, February 19, 2017

PSThar - Asynchronous execution and more

I made a few interesting additions to PSThar today. The first order of business was to make the scripts execute on a different thread so they could be stopped if they ran long or got into an infinite loop. While a script is running, the Run Script button changes into Stop Script and the other controls are disabled.

Since users probably wouldn't appreciate getting a deluge of single-tile undo entries from a single script, I made PSThar inspect the undo stack and roll up the actions caused by the script into a single entry that can be undone and redone with a single keystroke.

Finally, I wrote a Get-Level cmdlet that gets level wrappers by ID or name, or just gets them all if no parameters are specified.

Saturday, February 18, 2017

PSThar - Set-LevelTile cmdlet

There are several steps necessary to correctly change a tile from the Abiathar API. First the tile in the level itself has to be set, then the render planes need to be notified of the change, then the undo stack has to be updated. If not all of those three things go together, bizarre behavior will result. That's too much for every scripter to remember and implement correctly all the time, so I wrote up a Set-LevelTile cmdlet for PSThar that takes care of all the details.

That was slightly trickier than expected because there's no way to get the ID of a given level wrapper without using reflection and scanning through all the current levels. That API oversight is usually mitigated by tools' easy access to the current level ID, but PSThar scripts can affect any level. I used the reflection strategy here, but I'll try to figure out some nice new API feature so other extension authors don't have to.

Friday, February 17, 2017

PowerShell surprise: functions can break out of a loop in their caller

One might expect that the Break statement inside a function would cause the function to exit, or at least do nothing to its caller. I was very surprised to learn that it can indeed affect the control flow in the calling scope. Take this trivial function:

Function BreakTest {Break}

And this calling code:

for ($a = 0; $a -lt 5; $a++) {
 for ($b = 0; $b -lt 3; $b++) {
  BreakTest; "a = $a; b = $b"
 }; $a
}

The sprinkle of strings that one would expect to be output by the innermost "for" loop never comes; calling BreakTest exits the $b loop. The program just outputs the numbers from 0 to 4. If you remove the function call, you do indeed get a bunch of texts, with the plain $a's 0 through 4 interspersed.

Thursday, February 16, 2017

Arbitrary precision integers in PowerShell

If for some reason you find yourself in need of facilities for handling extremely large numbers with arbitrary precision in PowerShell, you can take advantage of the BigInteger type. First you'll need to load the assembly that contains it:

Add-Type -AssemblyName System.Numerics

You can then refer to the type as bigint. Operators on it work as you expect. One thing to note is that it does not have a constructor that takes a string. Rather, you need to use the static Parse method if you want to hold an arbitrarily large number without losing precision. If you tried to use a constructor with a string, the string would be converted to one of the normal numeric types, losing precision before bigint comes into play at all.

Wednesday, February 15, 2017

FMod - Skip initial profiles creation if possible

The configuration object that represents the templates file is very large and complicated, so it takes some time (on a computer's scale) to be built. On slow computers, opening the New Project Wizard visibly takes a moment, so it would be good to speed that up. In most circumstances, there already is a defaults.aconf file from which templates will be loaded, so it's completely pointless to generate the standard set only to have it overwritten with data from disk. I had already introduced an optional parameter to the configuration object's constructor that should skip the normal generation, but I apparently never actually implemented it. Today I did, achieving a tiny speedup. I need to make sure that change doesn't have unintended consequences, then I'll release a new version with the past few days' improvements.

Tuesday, February 14, 2017

PSThar: PowerShell for Abiathar

Several times, I have wished I could just make a little one-time change to Abiathar's state without editing the main code or taking the time to write a full extension. So yesterday, I made a little extension that allows me to do just that. PSThar embeds PowerShell in Abiathar, allowing user scripts to interact with the same object model that extensions do. The state manager is provided in the $Abiathar variable. It's currently extremely easy to corrupt Abiathar's bookkeeping by not using the API right, so I might create some cmdlets to handle that for the user.

Getting the names of all levels

Monday, February 13, 2017

Set-ADAccountPassword only respects history if -OldPassword is specified

Forcibly resetting a user's password in Active Directory - e.g. with the Set-ADAccountPassword cmdlet - does not respect the password history. This makes sense, since account operators should have no special knowledge about a user's password choices (other than the new forced password). Interestingly, though, resetting a password does not destroy the password history.

If you first force-reset the password to some known string by not supplying the -OldPassword parameter, you can then make another setting call that does supply -OldPassword (now the just-reset one), and that latter call will check the history. This does have the disadvantage of leaving the temporary password set if the second set fails, but it's interesting to observe.

Sunday, February 12, 2017

FMod - Bugs in v2.8.6

After the release of Abiathar v2.8.6, a PCKF member noticed a couple little bugs (and was very helpful by including specifics):

  • The Path Plotter crashes if pathing is not enabled for the current dependency file
  • Area-related (as opposed to single-spot-related) messages from the Level Inspector take the user to the wrong place when Zip To is used
I was able to fix both of these issues very easily thanks to the specific bug reports. I'll make sure everything else is working as intended before pushing these changes.

Saturday, February 11, 2017

FMod - v2.8.6

Today I went over the changes pending release, making sure everything works as intended. I just tweaked one thing: there were too many line breaks added by Generate Patches in one spot. I finagled that so everything is balanced.

Then I addressed something that's been bothering me for a while. The Path Plotter tool didn't show what you were going to get until you finished drawing the path (by clicking the turning points). Today I finally added that: it uses the paste preview plane to show where all the arrows would be placed if the path was finalized with the mouse at the current location.

These changes are live in the auto-updater as v2.8.6.

Friday, February 10, 2017

FMod - Secure updating

Now that I've figured out how to use Let's Encrypt in manual mode, I can fairly easily generate certificates for any domain I control. I did that for the PCKF and the Abiathar files hosting domain, abiathar.keenmodding.org, today. Since I didn't want to generate four different certificates, I moved the update and verimaps sub-subdomains to be folders in abiathar. All the various Abiathar components check for their online resources in the new secured location. With that done, I can see about releasing the new version very soon.

Thursday, February 9, 2017

Let's Encrypt and cPanel shared hosting

I decided to finally go through the process of manually generating a Let's Encrypt certificate for Namecheap shared hosting. I have no real Linux machine in my control, so I spun up an Ubuntu 16.04 VM. I then followed this guide to manually requesting a certificate. It was less difficult than I expected; I just had to create a file with the challenge content on the server before pushing the last button in the letsencrypt utility. Then I moved the resulting files fullchain.pem and privkey.pem out of the /etc/letsencrypt/live/mydomain.com folder (with sudo, because that directory is protected).

cPanel has an SSL/TLS section that allows the management of certificate/key files. PEM files are just text, so I copied and pasted their content into the certificate and private key creation text boxes, as appropriate. Finally, I assigned the key pair to the Keen Modding domain. It worked - connections to the forum can now be secured!

Now I just need to repeat the certificate generation for subdomains and my other sites.

Wednesday, February 8, 2017

The change that makes PowerShell classes' methods run in full-language mode

Yesterday, I noted that PowerShell-defined classes' method bodies are restricted by the runspaces in which they execute. That causes problems for some use cases, and I wanted to figure out how to fix it. Eventually, I found the place to change: InvokeHelper and InvokeHelperT in ClassOps.cs. Just add this line right before the InvokeAsMemberFunction and InvokeAsMemberFunctionT calls:

sb.LanguageMode = PSLanguageMode.FullLanguage;

Tuesday, February 7, 2017

PowerShell-defined classes' methods are restricted by the runspace they're invoked in

In PowerShell 5, you can define your own .NET types in a script. They can have fields and methods, just like all .NET classes. Method bodies are written in PowerShell. Therefore, you can implement full cmdlet types (not just advanced functions) in PowerShell and allow them to be used in constrained-language runspaces.

Unfortunately, when the method body is run from such a limited runspace, it is subject to the caller's restrictions. This doesn't appear to be for security reasons, since you could just define the type in C# with Add-Type and then approve that cmdlet type for execution in the runspace. Here is a script to test this:

Class TestCmdlet : System.Management.Automation.Cmdlet {
 [void]BeginProcessing() {
  $this.WriteObject('It worked!')
 }
}
$iss = [InitialSessionState]::Create()
$testssce = New-Object System.Management.Automation.Runspaces.SessionStateCmdletEntry ('Test-CustomCmdlet', [TestCmdlet], '')
$iss.Commands.Add($testssce)
$rs = [RunspaceFactory]::CreateRunspace($iss)
$rs.Open()
$rs.LanguageMode = 'ConstrainedLanguage'
$p = $rs.CreatePipeline('Test-CustomCmdlet')
$p.Invoke()

It should return the string It worked!, but it will actually fail with CmdletInvocationException because the script-defined type cannot call its own methods.

I have written a very simple change to a fork of the PowerShell code base that makes this example work. I will see if it can/should be implemented in the real PowerShell.

Monday, February 6, 2017

Building PowerShell when it complains about win10-x86 not being a valid value for a variable

Today I tried to compile the official PowerShell repository, but received an error that started with this:

"The variable cannot be validated because the value is not a valid value for the Runtime variable."

win10-x86 is apparently not one of the supported runtimes for the full-CLR version of PowerShell. I have 64-bit Windows 10, but the Git Shell always ran 32-bit PowerShell. It's possible that the 32-bitness of the calling program caused the dotnet utility to return the x86 version of the OS, but I'm not sure. Anyway, I ended up manually modifying build.psm1 to simply set $Runtime to win10-x64 on line 530, as opposed to running dotnet. Then the official instructions worked as expected.

Sunday, February 5, 2017

Volunteering at a different FTC league's meet

Though the local FTC league had its championship a week ago, other leagues are still doing normal meets. I volunteered at one of those yesterday. They had been in need of a field inspector; my local league's manager gave them my information since I had done field inspection several times before. Most of the time here, I was the only one doing the field inspecting, but the person overseeing the event helped when a bunch of teams came through at once. After inspections completed, I stuck around to be an assistant Field Technical Advisor. I don't know as much as I'd like to about the new phone systems, but we got through it.

The event was managed essentially the same as those of the other league. It was very nice that the host school provided a token for a free meal to each volunteer, redeemable at the concession stand. They had "volunteer" vests instead of lanyards, which was nice in that it more clearly showed where the volunteers were. The host school also had their band play between matches, filling the gaps while referees processed the just-completed game.

Friday, February 3, 2017

Namecheap explicitly does not support Let's Encrypt

I received a tip in regard to yesterday's post reminding me of Let's Encrypt, which is a really great and responsibly managed free TLS-certificate-granting project. Unfortunately, my shared hosting provider (Namecheap) does not give me root access with my current plan, which the normal Let's Encrypt program needs. Some shared hosting providers work with Let's Encrypt, but Namecheap is on the list of providers who explicitly do not plan to support it.

I can get SSH access (non-root) by request, so that might let me get free certificates onto the machine. I could always manually copy over a Let's Encrypt cert, but I would much rather have a setup that doesn't require me to set up another machine or VM. I did find this article and this other GitHub repository, which look promising. I'll see how it goes.

Thursday, February 2, 2017

FMod - Switching to Amazon S3

A month or so ago, I copied all the Abiathar-related hosted files from my public Dropbox onto the server that hosts Keen Modding and the PCKF, since Dropbox's public folder mechanism will stop working soonish. Unfortunately, I have no SSL certificate for my domains at the moment, and with StartSSL sinking, I can't easily get one. It would be a Very Bad Thing to do automatic updates over an unsecured connection, so that leaves Amazon S3. S3 gives me plenty of space at very little cost; I already pay $0.51 a month for DNS and file hosting, and I can't imagine these few files making that go up any more than a single cent per month. I uploaded all the files to it (which is a weirdly slow affair) and will soon readjust all the URLs embedded in the various Abiathar components.

Wednesday, February 1, 2017

FMod - Consistent tileinfo opacity

I noticed while adding the foreground highlight that the tile properties render plane behaved differently depending on whether it was drawing the level for the first time. (For performance reasons that may or may not make a difference, the "render the whole level" method doesn't use the "render this one changed tile" method.) Specifically, when replacing a tile, it uses a ColorMatrix to change the alpha component, but that doesn't happen for the first render pass. Therefore, tiles placed after loading the level get a brighter-looking tile property overlay. That's pretty strange, and the visual effect can be replicated perfectly fine by changing the color in the config file if desired, so I removed that extra complication to make it consistent.