An event with a TZID of "UTC" without an explicit VTIMEZONE named UTC is incorrectly interpreted as a local time even though a UTC timezone is built-in and handled in icaltimezone_get_builtin_timezone(). This is because icaltimezone_get_builtin_timezone_from_tzid() returns before calling icaltimezone_get_builtin_timezone() since "UTC" doesn't have three slashes in it.
I added a special case to the top of icaltimezone_get_builtin_timezone_from_tzid() that immediately calls icaltimezone_get_builtin_timezone() and returns the UTC timezone if the TZID is "UTC" or "GMT". I added GMT as well because some older clients will assume that GMT is a built-in timezone and generate VCALENDARs using GMT without including a corresponding VTIMEZONE (Lotus Notes does this for sure, I don't know what else does).
A better solution might be to remove the early exit for num_slashes != 3 in icaltimezone_get_builtin_timezone_from_tzid(), but I'm not sure why it was put there in the first place. It looks like this was added when the built-in timezone prefix stuff was added, but it essentially prevents icaltimezone_get_builtin_timezone() from ever getting called in some valid cases.