Affects: 5.3.8


You can create an Object like this

    @Test
    public void test() {
        SpelExpressionParser parser = new SpelExpressionParser();
        System.out.println(parser.parseRaw("new java..util......ArrayList()").getValue());
    }

because in org.springframework.expression.spel.standard.InternalSpelExpressionParser, line 722:

private SpelNodeImpl eatPossiblyQualifiedId() {
        Deque<SpelNodeImpl> qualifiedIdPieces = new ArrayDeque<>();
        Token node = peekToken();

        // this loop allows any number of dots
        while (isValidQualifiedId(node)) {
            nextToken();
            if (node.kind != TokenKind.DOT) {
                qualifiedIdPieces.add(new Identifier(node.stringValue(), node.startPos, node.endPos));
            }
            node = peekToken();
        }
        ...
}

// this method treats both DOT and IDENTIFIER as qualifiedId
private boolean isValidQualifiedId(@Nullable Token node) {
        if (node == null || node.kind == TokenKind.LITERAL_STRING) {
            return false;
        }
        if (node.kind == TokenKind.DOT || node.kind == TokenKind.IDENTIFIER) {
            return true;
        }
        String value = node.stringValue();
        return (StringUtils.hasLength(value) && VALID_QUALIFIED_ID_PATTERN.matcher(value).matches());
}

This doesn't cause any problem, but I think it lacks preciseness.

Comment From: sbrannen

Superseded by #27630