curl_get_line: make sure lines end with newline

Verify with test 792 and 793

Reported-by: z2_
Closes #17697
This commit is contained in:
Daniel Stenberg 2025-06-21 22:35:41 +02:00
parent e29f11f2d6
commit 52f58ebb10
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 123 additions and 11 deletions

View File

@ -32,6 +32,15 @@
/* The last #include file should be: */
#include "memdebug.h"
static int appendnl(struct dynbuf *buf)
{
CURLcode result = curlx_dyn_addn(buf, "\n", 1);
if(result)
/* too long line or out of memory */
return 0; /* error */
return 1; /* all good */
}
/*
* Curl_get_line() makes sure to only return complete whole lines that end
* newlines.
@ -43,9 +52,10 @@ int Curl_get_line(struct dynbuf *buf, FILE *input)
curlx_dyn_reset(buf);
while(1) {
char *b = fgets(buffer, sizeof(buffer), input);
size_t rlen;
if(b) {
size_t rlen = strlen(b);
rlen = strlen(b);
if(!rlen)
break;
@ -59,19 +69,24 @@ int Curl_get_line(struct dynbuf *buf, FILE *input)
/* end of the line */
return 1; /* all good */
else if(feof(input)) {
else if(feof(input))
/* append a newline */
result = curlx_dyn_addn(buf, "\n", 1);
if(result)
/* too long line or out of memory */
return 0; /* error */
return appendnl(buf);
}
else {
rlen = curlx_dyn_len(buf);
if(rlen) {
b = curlx_dyn_ptr(buf);
if(b[rlen-1] != '\n')
/* append a newline */
return appendnl(buf);
return 1; /* all good */
}
else
break;
}
else if(curlx_dyn_len(buf))
return 1; /* all good */
else
break;
}
return 0;
}

View File

@ -110,7 +110,7 @@ test736 test737 test738 test739 test740 test741 test742 test743 test744 \
test745 test746 test747 test748 test749 test750 test751 test752 test753 \
test754 \
test780 test781 test782 test783 test784 test785 test786 test787 test788 \
test789 test790 test791 \
test789 test790 test791 test792 test793 \
\
test799 test800 test801 test802 test803 test804 test805 test806 test807 \
test808 test809 test810 test811 test812 test813 test814 test815 test816 \

View File

@ -3,6 +3,7 @@
<keywords>
HTTP
--netrc-file
netrc
</keywords>
</info>

48
tests/data/test792 Normal file
View File

@ -0,0 +1,48 @@
<testcase>
<info>
<keywords>
netrc
FTP
</keywords>
</info>
#
# Server-side
<reply>
<data>
content
</data>
</reply>
#
# Client-side
<client>
<server>
ftp
</server>
<features>
proxy
</features>
<name>
.netrc with embedded NULL byte
</name>
<command>
--netrc --netrc-file %LOGDIR/netrc%TESTNUMBER ftp://%HOSTIP:%FTPPORT/%TESTNUMBER
</command>
<file name="%LOGDIR/netrc%TESTNUMBER" >
machine %HOSTIP login username password%hex[%00]hex% hello
</file>
</client>
<verify>
<protocol crlf="yes">
USER username
PASS
PWD
EPSV
TYPE I
SIZE %TESTNUMBER
RETR %TESTNUMBER
QUIT
</protocol>
</verify>
</testcase>

48
tests/data/test793 Normal file
View File

@ -0,0 +1,48 @@
<testcase>
<info>
<keywords>
netrc
FTP
</keywords>
</info>
#
# Server-side
<reply>
<data>
content
</data>
</reply>
#
# Client-side
<client>
<server>
ftp
</server>
<features>
proxy
</features>
<name>
.netrc with embedded NULL byte, with quoted token
</name>
<command>
--netrc --netrc-file %LOGDIR/netrc%TESTNUMBER ftp://%HOSTIP:%FTPPORT/%TESTNUMBER
</command>
<file name="%LOGDIR/netrc%TESTNUMBER" >
machine %HOSTIP login username "password"%hex[%00]hex% hello
</file>
</client>
<verify>
<protocol crlf="yes">
USER username
PASS
PWD
EPSV
TYPE I
SIZE %TESTNUMBER
RETR %TESTNUMBER
QUIT
</protocol>
</verify>
</testcase>