if(result)
return result;
buf = buf_alloc;
+
+ /* A decoded CR or LF would terminate the single-line gopher request and
+ let a crafted URL smuggle additional bytes onto the wire. REJECT_ZERO
+ only blocks NUL; reject CR and LF here too. A TAB is left alone as it
+ is the legitimate gopher type-7 selector/search separator. */
+ if(memchr(buf, '\r', buf_len) || memchr(buf, '\n', buf_len)) {
+ curlx_free(buf_alloc);
+ failf(data, "Bad gopher selector, CR or LF not allowed");
+ return CURLE_URL_MALFORMAT;
+ }
}
for(; buf_len;) {
test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 \
test1589 test1590 test1591 test1592 test1593 test1594 test1595 test1596 \
test1597 test1598 test1599 test1600 test1601 test1602 test1603 test1604 \
-test1605 test1606 test1607 test1608 test1610 test1611 test1612 \
+test1605 test1606 test1607 test1608 test1609 test1610 test1611 test1612 \
test1613 test1614 test1615 test1616 test1617 test1618 test1619 test1620 \
test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 \
test1629 test1630 test1631 test1632 test1633 test1634 test1635 test1636 \
--- /dev/null
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+GOPHER
+CRLF-in-URL
+</keywords>
+</info>
+
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+gopher
+</server>
+<name>
+Gopher with URL-encoded CR LF in the selector
+</name>
+<command>
+gopher://%HOSTIP:%GOPHERPORT/1/sel%0d%0aINJECT/%TESTNUMBER
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+# 3 - CURLE_URL_MALFORMAT
+<errorcode>
+3
+</errorcode>
+# nothing must reach the server, the selector is rejected before any send
+<protocol nonewline="yes">
+
+</protocol>
+</verify>
+</testcase>