/* Possible phony file extension. */
#define UNICRASH_PHONY_EXTENSION ((__force badname_t)(1U << 6))
+/* More than one variation selector in a row. */
+#define UNICRASH_VARIATION_RUN ((__force badname_t)(1U << 7))
+
/* FULL STOP (aka period), 0x2E */
#define UCHAR_PERIOD ((UChar32)'.')
UChar32 uchr;
uint8_t mask = 0;
unsigned int ret = 0;
+ /* Don't allow the first codepoint to be a variation */
+ UBool was_variation = true;
uiter_setString(&uiter, entry->normstr, entry->normstrlen);
while ((uchr = uiter_next32(&uiter)) != U_SENTINEL) {
+ UBool is_variation =
+ u_hasBinaryProperty(uchr, UCHAR_VARIATION_SELECTOR);
+
/* characters are invisible */
if (is_nonrendering(uchr))
ret |= UNICRASH_INVISIBLE;
default:
break;
}
+
+ if (is_variation && was_variation)
+ ret |= UNICRASH_VARIATION_RUN;
+
+ was_variation = is_variation;
}
/* mixing left-to-right and right-to-left chars */
goto out;
}
+ /*
+ * Variation codepoints only apply to the previous non-variation
+ * codepoint. Seeing multiple in a row or at the start of a name is
+ * weird.
+ */
+ if (badflags & UNICRASH_VARIATION_RUN) {
+ str_warn(uc->ctx, descr_render(dsc),
+_("Unicode name \"%s\" in %s contains a weird sequence of variation selectors."),
+ bad1, what);
+ goto out;
+ }
+
/*
* Skip the informational messages if the inode owning the name is
* only writeable by root, because those files were put there by the