View | Details | Raw Unified | Return to bug 55917
Collapse All | Expand All

(-)java/org/apache/tomcat/util/http/Cookies.java (-8 / +29 lines)
Lines 508-521 Link Here
508
    private static final int getTokenEndPosition(byte bytes[], int off, int end,
508
    private static final int getTokenEndPosition(byte bytes[], int off, int end,
509
            int version, boolean isName){
509
            int version, boolean isName){
510
        int pos = off;
510
        int pos = off;
511
        while (pos < end &&
511
        while (pos < end && allowInToken(bytes[pos], version, isName)) {
512
                (!CookieSupport.isHttpSeparator((char)bytes[pos]) ||
513
                 version == 0 &&
514
                        CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
515
                        bytes[pos] != '=' &&
516
                        !CookieSupport.isV0Separator((char)bytes[pos]) ||
517
                 !isName && bytes[pos] == '=' &&
518
                         CookieSupport.ALLOW_EQUALS_IN_VALUE)) {
519
            pos++;
512
            pos++;
520
        }
513
        }
521
514
Lines 525-530 Link Here
525
        return pos;
518
        return pos;
526
    }
519
    }
527
520
521
    private static boolean allowInToken(byte b, int version, boolean isName) {
522
        // byte is signed so cast into a positive int for comparisons
523
        int octet = ((int)b) & 0xff;
524
525
        // disallow all controls
526
        if (octet < 0x20 && octet != 0x09 || octet >= 0x7f && octet < 0xa0) {
527
            throw new IllegalArgumentException(
528
                    "Control character in cookie value or attribute.");
529
        }
530
531
        // values 0xa0-0xff are allowed in V0 values, otherwise disallow
532
        if (octet >= 0x80) {
533
            if (isName || version != 0) {
534
                throw new IllegalArgumentException(
535
                        "Control character in cookie value or attribute.");
536
            }
537
            return true;
538
        }
539
540
        return !CookieSupport.isHttpSeparator((char) b) ||
541
                version == 0 &&
542
                        CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
543
                        b != '=' &&
544
                        !CookieSupport.isV0Separator((char) b) ||
545
                !isName && b == '=' &&
546
                        CookieSupport.ALLOW_EQUALS_IN_VALUE;
547
    }
548
528
    /**
549
    /**
529
     * Given a starting position after an initial quote character, this gets
550
     * Given a starting position after an initial quote character, this gets
530
     * the position of the end quote. This escapes anything after a '\' char
551
     * the position of the end quote. This escapes anything after a '\' char
(-)test/org/apache/tomcat/util/http/TestCookies.java (+97 lines)
Lines 17-27 Link Here
17
17
18
package org.apache.tomcat.util.http;
18
package org.apache.tomcat.util.http;
19
19
20
import java.nio.charset.StandardCharsets;
21
22
import javax.servlet.http.Cookie;
23
24
import org.junit.Assert;
25
import org.junit.Before;
26
import org.junit.Ignore;
20
import org.junit.Test;
27
import org.junit.Test;
21
28
22
public class TestCookies {
29
public class TestCookies {
30
    private Cookies cookies;
23
31
32
    @Before
33
    public void init() {
34
        this.cookies = new Cookies(null);
35
    }
36
37
    @Test(expected = IllegalArgumentException.class)
38
    public void disallow8bitInName() {
39
        process("f\u00f6o=bar");
40
    }
41
42
    @Test(expected = IllegalArgumentException.class)
43
    public void disallowControlInName() {
44
        process("f\010o=bar");
45
    }
46
47
    @Test(expected = IllegalArgumentException.class)
48
    public void disallow8BitControlInName() {
49
        process("f\210o=bar");
50
    }
51
24
    @Test
52
    @Test
53
    public void allow8BitInV0Value() {
54
        process("foo=b\u00e1r");
55
        expect(makeCookie("foo", "b\u00e1r", 0));
56
    }
57
58
    @Test(expected = IllegalArgumentException.class)
59
    public void disallow8bitInV1UnquotedValue() {
60
        process("$Version=1; foo=b\u00e1r");
61
    }
62
63
    @Test
64
    public void allow8bitInV1QuotedValue() {
65
        process("$Version=1; foo=\"b\u00e1r\"");
66
        expect(makeCookie("foo", "b\u00e1r", 1));
67
    }
68
69
    @Test(expected = IllegalArgumentException.class)
70
    public void disallowControlInV0Value() {
71
        process("foo=b\010r");
72
    }
73
74
    @Test(expected = IllegalArgumentException.class)
75
    public void disallow8BitControlInV0Value() {
76
        process("foo=b\210r");
77
    }
78
79
    @Test(expected = IllegalArgumentException.class)
80
    public void disallowControlInV1UnquotedValue() {
81
        process("$Version=1; foo=b\010r");
82
    }
83
84
    @Ignore
85
    @Test(expected = IllegalArgumentException.class)
86
    public void disallowControlInV1QuotedValue() {
87
        process("$Version=1; foo=\"b\010r\"");
88
    }
89
90
    @Test(expected = IllegalArgumentException.class)
91
    public void disallow8BitControlInV1UnquotedValue() {
92
        process("$Version=1; foo=b\210r");
93
    }
94
95
    @Ignore
96
    @Test(expected = IllegalArgumentException.class)
97
    public void disallow8BitControlInV1QuotedValue() {
98
        process("$Version=1; foo=\"b\210r\"");
99
    }
100
101
    private void process(String header) {
102
        byte[] bytes = header.getBytes(StandardCharsets.ISO_8859_1);
103
        cookies.processCookieHeader(bytes, 0, bytes.length);
104
    }
105
106
    private void expect(Cookie... expected) {
107
        Assert.assertEquals(expected.length, cookies.getCookieCount());
108
        for (int i = 0; i < expected.length; i++) {
109
            ServerCookie actual = cookies.getCookie(i);
110
            Assert.assertEquals(expected[i].getName(), actual.getName().toString());
111
            Assert.assertEquals(expected[i].getValue(), actual.getValue().toString());
112
        }
113
    }
114
115
    private static Cookie makeCookie(String name, String value, int version) {
116
        Cookie cookie = new Cookie(name, value);
117
        cookie.setVersion(version);
118
        return cookie;
119
    }
120
121
    @Test
25
    public void testCookies() throws Exception {
122
    public void testCookies() throws Exception {
26
        test("foo=bar; a=b", "foo", "bar", "a", "b");
123
        test("foo=bar; a=b", "foo", "bar", "a", "b");
27
        test("foo=bar;a=b", "foo", "bar", "a", "b");
124
        test("foo=bar;a=b", "foo", "bar", "a", "b");

Return to bug 55917