NaikSoftware / StompProtocolAndroid

STOMP protocol via WebSocket for Android
MIT License
597 stars 265 forks source link

NoSuchElementException when STOMP Frame's header line contains SPACE character in name or value part #198

Open AndrewShen812 opened 3 years ago

AndrewShen812 commented 3 years ago

Problem

There will be NoSuchElementException when StompMessage.from() method parses STOMP frame which contains SPACE character in the name or value part in header line. The main code which caused this issue:

    private static final Pattern PATTERN_HEADER = Pattern.compile("([^:\\s]+)\\s*:\\s*([^:\\s]+)");
    public static StompMessage from(@Nullable String data) {
        // ...
        while (reader.hasNext(PATTERN_HEADER)) {
            Matcher matcher = PATTERN_HEADER.matcher(reader.next());
            matcher.find();
            headers.add(new StompHeader(matcher.group(1), matcher.group(2)));
        }

        reader.skip("\n\n");
         // ...
    }

The regex means, ':' and all whitespace characters(space, \t, \n, \r, etc) are not allowed in header lines' name or value part. As a result, reader.hasNext will return false when handle a header line contains SPACE character in name or value part, then reader.skip("\n\n") throws NoSuchElementException.

In fact, it's reasonable to contain SPACE characters in header's value part, as mentioned in the STOMP Protocol Specification 1.2 - ERROR Frame :

ERROR receipt-id:message-12345 content-type:text/plain content-length:170 message:malformed frame received

Solution

According to the STOMP Protocol Specification 1.2 - Augmented BNF,only CR or LF or ":" is not allowed in header's name or value part, so the PATTERN_HEADER constant should be changed to: private static final Pattern PATTERN_HEADER = Pattern.compile("([^:\\n\\r]+)\\s*:\\s*([^:\\n\\r]+)");