33 #include <libtorrent/error_code.hpp>
35 #include <QDataStream>
47 unsigned char octetIndex = 0;
49 const char *octetStart = str;
55 const long int extractedNum = strtol(octetStart, &endptr, 10);
56 if ((extractedNum >= 0L) && (extractedNum <= 255L))
57 m_buf[octetIndex++] =
static_cast<unsigned char>(extractedNum);
70 if (str != octetStart)
72 const long int extractedNum = strtol(octetStart, &endptr, 10);
73 if ((extractedNum >= 0L) && (extractedNum <= 255L))
74 m_buf[octetIndex] =
static_cast<unsigned char>(strtol(octetStart, &endptr, 10));
78 if ((endptr == str) && (octetIndex == 3))
85 lt::address_v4::bytes_type
parsed()
const
91 lt::address_v4::bytes_type
m_buf;
100 address = lt::address_v4(parser.
parsed());
102 address = lt::make_address(data, ec);
128 if (!
file.exists())
return ruleCount;
130 if (!
file.open(QIODevice::ReadOnly | QIODevice::Text))
137 qint64 bytesRead = 0;
142 int parseErrorCount = 0;
143 const auto addLog = [&parseErrorCount](
const QString &msg)
151 bytesRead =
file.read(buffer.data() + offset,
BUFFER_SIZE - offset - 1);
154 const int dataSize = bytesRead + offset;
155 if ((bytesRead == 0) && (dataSize == 0))
158 for (start = 0; start < dataSize; ++start)
162 if (!((bytesRead == 0) && (dataSize > 0)))
164 for (
int i = start; i < dataSize; ++i)
166 if (buffer[i] ==
'\n')
179 endOfLine = dataSize;
180 buffer[dataSize] =
'\0';
187 offset = dataSize - start;
188 memmove(buffer.data(), buffer.data() + start, offset);
194 if ((buffer[start] ==
'#')
195 || ((buffer[start] ==
'/') && ((start + 1 < dataSize) && (buffer[start + 1] ==
'/'))))
205 if (firstComma != -1)
209 if (firstComma != -1)
212 const long int nbAccess = strtol(buffer.data() + firstComma + 1,
nullptr, 10);
222 const int endOfIPRange = ((firstComma == -1) ? (endOfLine - 1) : (firstComma - 1));
227 addLog(tr(
"IP filter line %1 is malformed.").arg(nbLine));
232 lt::address startAddr;
233 int newStart =
trim(buffer.data(), start, delimIP - 1);
237 addLog(tr(
"IP filter line %1 is malformed. Start IP of the range is malformed.").arg(nbLine));
243 newStart =
trim(buffer.data(), delimIP + 1, endOfIPRange);
247 addLog(tr(
"IP filter line %1 is malformed. End IP of the range is malformed.").arg(nbLine));
252 if ((startAddr.is_v4() != endAddr.is_v4())
253 || (startAddr.is_v6() != endAddr.is_v6()))
256 addLog(tr(
"IP filter line %1 is malformed. One IP is IPv4 and the other is IPv6!").arg(nbLine));
266 m_filter.add_rule(startAddr, endAddr, lt::ip_filter::blocked);
269 catch (
const std::exception &
e)
272 addLog(tr(
"IP filter exception thrown for line %1. Exception is: %2")
273 .arg(nbLine).arg(QString::fromLocal8Bit(
e.what())));
277 if (start >= dataSize)
282 LogMsg(tr(
"%1 extra IP filter parsing errors occurred.",
"513 extra IP filter parsing errors occurred.")
292 if (!
file.exists())
return ruleCount;
294 if (!
file.open(QIODevice::ReadOnly | QIODevice::Text))
301 qint64 bytesRead = 0;
306 int parseErrorCount = 0;
307 const auto addLog = [&parseErrorCount](
const QString &msg)
315 bytesRead =
file.read(buffer.data() + offset,
BUFFER_SIZE - offset - 1);
318 const int dataSize = bytesRead + offset;
319 if ((bytesRead == 0) && (dataSize == 0))
322 for (start = 0; start < dataSize; ++start)
326 if (!((bytesRead == 0) && (dataSize > 0)))
328 for (
int i = start; i < dataSize; ++i)
330 if (buffer[i] ==
'\n')
343 endOfLine = dataSize;
344 buffer[dataSize] =
'\0';
351 offset = dataSize - start;
352 memmove(buffer.data(), buffer.data() + start, offset);
358 if ((buffer[start] ==
'#')
359 || ((buffer[start] ==
'/') && ((start + 1 < dataSize) && (buffer[start + 1] ==
'/'))))
369 if (partsDelimiter == -1)
372 addLog(tr(
"IP filter line %1 is malformed.").arg(nbLine));
382 addLog(tr(
"IP filter line %1 is malformed.").arg(nbLine));
387 lt::address startAddr;
388 int newStart =
trim(buffer.data(), partsDelimiter + 1, delimIP - 1);
392 addLog(tr(
"IP filter line %1 is malformed. Start IP of the range is malformed.").arg(nbLine));
398 newStart =
trim(buffer.data(), delimIP + 1, endOfLine);
402 addLog(tr(
"IP filter line %1 is malformed. End IP of the range is malformed.").arg(nbLine));
407 if ((startAddr.is_v4() != endAddr.is_v4())
408 || (startAddr.is_v6() != endAddr.is_v6()))
411 addLog(tr(
"IP filter line %1 is malformed. One IP is IPv4 and the other is IPv6!").arg(nbLine));
420 m_filter.add_rule(startAddr, endAddr, lt::ip_filter::blocked);
423 catch (
const std::exception &
e)
426 addLog(tr(
"IP filter exception thrown for line %1. Exception is: %2")
427 .arg(nbLine).arg(QString::fromLocal8Bit(
e.what())));
431 if (start >= dataSize)
436 LogMsg(tr(
"%1 extra IP filter parsing errors occurred.",
"513 extra IP filter parsing errors occurred.")
448 read = stream.readRawData(&c, 1);
473 if (!
file.exists())
return ruleCount;
475 if (!
file.open(QIODevice::ReadOnly))
481 QDataStream stream(&
file);
484 unsigned char version;
485 if (!stream.readRawData(buf,
sizeof(buf))
486 || memcmp(buf,
"\xFF\xFF\xFF\xFFP2B", 7)
487 || !stream.readRawData(
reinterpret_cast<char*
>(&version),
sizeof(version)))
489 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
493 if ((version == 1) || (version == 2))
495 qDebug (
"p2b version 1 or 2");
496 unsigned int start, end;
501 if (!stream.readRawData(
reinterpret_cast<char*
>(&start),
sizeof(start))
502 || !stream.readRawData(
reinterpret_cast<char*
>(&end),
sizeof(end)))
504 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
511 const lt::address_v4 first(ntohl(start));
512 const lt::address_v4 last(ntohl(end));
516 m_filter.add_rule(first, last, lt::ip_filter::blocked);
519 catch (
const std::exception &) {}
522 else if (version == 3)
524 qDebug (
"p2b version 3");
525 unsigned int namecount;
526 if (!stream.readRawData(
reinterpret_cast<char*
>(&namecount),
sizeof(namecount)))
528 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
532 namecount = ntohl(namecount);
534 for (
unsigned int i = 0; i < namecount; ++i)
539 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
547 unsigned int rangecount;
548 if (!stream.readRawData(
reinterpret_cast<char*
>(&rangecount),
sizeof(rangecount)))
550 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
554 rangecount = ntohl(rangecount);
555 unsigned int name, start, end;
556 for (
unsigned int i = 0; i < rangecount; ++i)
558 if (!stream.readRawData(
reinterpret_cast<char*
>(&name),
sizeof(name))
559 || !stream.readRawData(
reinterpret_cast<char*
>(&start),
sizeof(start))
560 || !stream.readRawData(
reinterpret_cast<char*
>(&end),
sizeof(end)))
562 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
569 const lt::address_v4 first(ntohl(start));
570 const lt::address_v4 last(ntohl(end));
574 m_filter.add_rule(first, last, lt::ip_filter::blocked);
577 catch (
const std::exception &) {}
584 LogMsg(tr(
"Parsing Error: The filter file is not a valid PeerGuardian P2B file."),
Log::CRITICAL);
618 qDebug(
"Processing filter file");
620 if (
m_filePath.endsWith(
".p2p", Qt::CaseInsensitive))
625 else if (
m_filePath.endsWith(
".p2b", Qt::CaseInsensitive))
630 else if (
m_filePath.endsWith(
".dat", Qt::CaseInsensitive))
642 catch (
const std::exception &)
647 qDebug(
"IP Filter thread: finished parsing, filter applied");
654 for (
int i = start; i <= end; ++i)
656 if (data[i] == delimiter)
665 for (
int i = end; i >= start; --i)
667 if (data[i] == delimiter)
680 if (start >= end)
return start;
681 int newStart = start;
683 for (
int i = start; i <= end; ++i)
685 if (isspace(data[i]) != 0)
696 for (
int i = end; i >= start; --i)
698 if (isspace(data[i]) != 0)
void processFilterFile(const QString &filePath)
FilterParserThread(QObject *parent=nullptr)
int findAndNullDelimiter(char *const data, char delimiter, int start, int end, bool reverse=false)
void IPFilterParsed(int ruleCount)
int trim(char *const data, int start, int end)
int getlineInStream(QDataStream &stream, std::string &name, char delim)
lt::address_v4::bytes_type parsed() const
bool tryParse(const char *str)
lt::address_v4::bytes_type m_buf
void LogMsg(const QString &message, const Log::MsgType &type)
bool parseIPAddress(const char *data, lt::address &address)
const int MAX_LOGGED_ERRORS
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts") set_source_files_properties($