diff options
Diffstat (limited to 'tests/auto/corelib/text/qbytearray')
-rw-r--r-- | tests/auto/corelib/text/qbytearray/.gitattributes | 1 | ||||
-rw-r--r-- | tests/auto/corelib/text/qbytearray/CMakeLists.txt | 29 | ||||
-rw-r--r-- | tests/auto/corelib/text/qbytearray/android_testdata.qrc | 5 | ||||
-rw-r--r-- | tests/auto/corelib/text/qbytearray/rfc3252.txt | 899 | ||||
-rw-r--r-- | tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp | 787 | ||||
-rw-r--r-- | tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm | 33 |
6 files changed, 624 insertions, 1130 deletions
diff --git a/tests/auto/corelib/text/qbytearray/.gitattributes b/tests/auto/corelib/text/qbytearray/.gitattributes deleted file mode 100644 index e04709aa2e..0000000000 --- a/tests/auto/corelib/text/qbytearray/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -rfc3252.txt -crlf diff --git a/tests/auto/corelib/text/qbytearray/CMakeLists.txt b/tests/auto/corelib/text/qbytearray/CMakeLists.txt index 57f73f6672..34307d9d44 100644 --- a/tests/auto/corelib/text/qbytearray/CMakeLists.txt +++ b/tests/auto/corelib/text/qbytearray/CMakeLists.txt @@ -1,18 +1,21 @@ -# Generated from qbytearray.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qbytearray Test: ##################################################################### -# Collect test data -list(APPEND test_data "rfc3252.txt") +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qbytearray LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() qt_internal_add_test(tst_qbytearray SOURCES tst_qbytearray.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate - TESTDATA ${test_data} ) ## Scopes: @@ -21,20 +24,6 @@ qt_internal_add_test(tst_qbytearray qt_internal_extend_target(tst_qbytearray CONDITION APPLE SOURCES tst_qbytearray_mac.mm - PUBLIC_LIBRARIES + LIBRARIES ${FWFoundation} ) - -if(ANDROID) - # Resources: - set(android_testdata_resource_files - "rfc3252.txt" - ) - - qt_internal_add_resource(tst_qbytearray "android_testdata" - PREFIX - "/" - FILES - ${android_testdata_resource_files} - ) -endif() diff --git a/tests/auto/corelib/text/qbytearray/android_testdata.qrc b/tests/auto/corelib/text/qbytearray/android_testdata.qrc deleted file mode 100644 index 5d42f0f627..0000000000 --- a/tests/auto/corelib/text/qbytearray/android_testdata.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>rfc3252.txt</file> - </qresource> -</RCC> diff --git a/tests/auto/corelib/text/qbytearray/rfc3252.txt b/tests/auto/corelib/text/qbytearray/rfc3252.txt deleted file mode 100644 index b80c61bf0a..0000000000 --- a/tests/auto/corelib/text/qbytearray/rfc3252.txt +++ /dev/null @@ -1,899 +0,0 @@ - - - - - - -Network Working Group H. Kennedy -Request for Comments: 3252 Mimezine -Category: Informational 1 April 2002 - - - Binary Lexical Octet Ad-hoc Transport - -Status of this Memo - - This memo provides information for the Internet community. It does - not specify an Internet standard of any kind. Distribution of this - memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (2002). All Rights Reserved. - -Abstract - - This document defines a reformulation of IP and two transport layer - protocols (TCP and UDP) as XML applications. - -1. Introduction - -1.1. Overview - - This document describes the Binary Lexical Octet Ad-hoc Transport - (BLOAT): a reformulation of a widely-deployed network-layer protocol - (IP [RFC791]), and two associated transport layer protocols (TCP - [RFC793] and UDP [RFC768]) as XML [XML] applications. It also - describes methods for transporting BLOAT over Ethernet and IEEE 802 - networks as well as encapsulating BLOAT in IP for gatewaying BLOAT - across the public Internet. - -1.2. Motivation - - The wild popularity of XML as a basis for application-level protocols - such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple - Object Access Protocol [SOAP], and Jabber [JABBER] prompted - investigation into the possibility of extending the use of XML in the - protocol stack. Using XML at both the transport and network layer in - addition to the application layer would provide for an amazing amount - of power and flexibility while removing dependencies on proprietary - and hard-to-understand binary protocols. This protocol unification - would also allow applications to use a single XML parser for all - aspects of their operation, eliminating developer time spent figuring - out the intricacies of each new protocol, and moving the hard work of - - - - -Kennedy Informational [Page 1] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - parsing to the XML toolset. The use of XML also mitigates concerns - over "network vs. host" byte ordering which is at the root of many - network application bugs. - -1.3. Relation to Existing Protocols - - The reformulations specified in this RFC follow as closely as - possible the spirit of the RFCs on which they are based, and so MAY - contain elements or attributes that would not be needed in a pure - reworking (e.g. length attributes, which are implicit in XML.) - - The layering of network and transport protocols are maintained in - this RFC despite the optimizations that could be made if the line - were somewhat blurred (i.e. merging TCP and IP into a single, larger - element in the DTD) in order to foster future use of this protocol as - a basis for reformulating other protocols (such as ICMP.) - - Other than the encoding, the behavioral aspects of each of the - existing protocols remain unchanged. Routing, address spaces, TCP - congestion control, etc. behave as specified in the extant standards. - Adapting to new standards and experimental algorithm heuristics for - improving performance will become much easier once the move to BLOAT - has been completed. - -1.4. Requirement Levels - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in BCP 14, RFC 2119 - [RFC2119]. - -2. IPoXML - - This protocol MUST be implemented to be compliant with this RFC. - IPoXML is the root protocol REQUIRED for effective use of TCPoXML - (section 3.) and higher-level application protocols. - - The DTD for this document type can be found in section 7.1. - - The routing of IPoXML can be easily implemented on hosts with an XML - parser, as the regular structure lends itself handily to parsing and - validation of the document/datagram and then processing the - destination address, TTL, and checksum before sending it on to its - next-hop. - - The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the - wider deployment of IPv4 and the fact that implementing IPv6 as XML - would have exceeded the 1500 byte Ethernet MTU. - - - -Kennedy Informational [Page 2] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - All BLOAT implementations MUST use - and specify - the UTF-8 encoding - of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well- - formed and include the XMLDecl. - -2.1. IP Description - - A number of items have changed (for the better) from the original IP - specification. Bit-masks, where present have been converted into - human-readable values. IP addresses are listed in their dotted- - decimal notation [RFC1123]. Length and checksum values are present - as decimal integers. - - To calculate the length and checksum fields of the IP element, a - canonicalized form of the element MUST be used. The canonical form - SHALL have no whitespace (including newline characters) between - elements and only one space character between attributes. There - SHALL NOT be a space following the last attribute in an element. - - An iterative method SHOULD be used to calculate checksums, as the - length field will vary based on the size of the checksum. - - The payload element bears special attention. Due to the character - set restrictions of XML, the payload of IP datagrams (which MAY - contain arbitrary data) MUST be encoded for transport. This RFC - REQUIRES the contents of the payload to be encoded in the base-64 - encoding of RFC 2045 [RFC2045], but removes the requirement that the - encoded output MUST be wrapped on 76-character lines. - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 3] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -2.2. Example Datagram - - The following is an example IPoXML datagram with an empty payload: - - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> - <ip> - <header length="474"> - <version value="4"/> - <tos precedence="Routine" delay="Normal" throughput="Normal" - relibility="Normal" reserved="0"/> - <total.length value="461"/> - <id value="1"/> - <flags reserved="0" df="dont" mf="last"/> - <offset value="0"/> - <ttl value="255"/> - <protocol value="6"/> - <checksum value="8707"/> - <source address="10.0.0.22"/> - <destination address="10.0.0.1"/> - <options> - <end copied="0" class="0" number="0"/> - </options> - <padding pad="0"/> - </header> - <payload> - </payload> - </ip> - -3. TCPoXML - - This protocol MUST be implemented to be compliant with this RFC. The - DTD for this document type can be found in section 7.2. - -3.1. TCP Description - - A number of items have changed from the original TCP specification. - Bit-masks, where present have been converted into human-readable - values. Length and checksum and port values are present as decimal - integers. - - To calculate the length and checksum fields of the TCP element, a - canonicalized form of the element MUST be used as in section 2.1. - - An iterative method SHOULD be used to calculate checksums as in - section 2.1. - - The payload element MUST be encoded as in section 2.1. - - - -Kennedy Informational [Page 4] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - The TCP offset element was expanded to a maximum of 255 from 16 to - allow for the increased size of the header in XML. - - TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header - as well as the <!DOCTYPE> declaration. - -3.2. Example Datagram - - The following is an example TCPoXML datagram with an empty payload: - - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> - <tcp> - <tcp.header> - <src port="31415"/> - <dest port="42424"/> - <sequence number="322622954"/> - <acknowledgement number="689715995"/> - <offset number=""/> - <reserved value="0"/> - <control syn="1" ack="1"/> - <window size="1"/> - <urgent pointer="0"/> - <checksum value="2988"/> - <tcp.options> - <tcp.end kind="0"/> - </tcp.options> - <padding pad="0"/> - </tcp.header> - <payload> - </payload> - </tcp> - -4. UDPoXML - - This protocol MUST be implemented to be compliant with this RFC. The - DTD for this document type can be found in section 7.3. - -4.1. UDP Description - - A number of items have changed from the original UDP specification. - Bit-masks, where present have been converted into human-readable - values. Length and checksum and port values are present as decimal - integers. - - - - - - - -Kennedy Informational [Page 5] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - To calculate the length and checksum fields of the UDP element, a - canonicalized form of the element MUST be used as in section 2.1. An - iterative method SHOULD be used to calculate checksums as in section - 2.1. - - The payload element MUST be encoded as in section 2.1. - - UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header - as well as the <!DOCTYPE> declaration. - -4.2. Example Datagram - - The following is an example UDPoXML datagram with an empty payload: - - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> - <udp> - <udp.header> - <src port="31415"/> - <dest port="42424"/> - <udp.length value="143"/> - <checksum value="2988"/> - </udp.header> - <payload> - </payload> - </udp> - -5. Network Transport - - This document provides for the transmission of BLOAT datagrams over - two common families of physical layer transport. Future RFCs will - address additional transports as routing vendors catch up to the - specification, and we begin to see BLOAT routed across the Internet - backbone. - -5.1. Ethernet - - BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the - exception that the type field of the Ethernet frame MUST contain the - value 0xBEEF. The first 5 octets of the Ethernet frame payload will - be 0x3c 3f 78 6d 6c ("<?xml".) - -5.2. IEEE 802 - - BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except - that the protocol type code for IPoXML is 0xBEEF. - - - - - -Kennedy Informational [Page 6] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -6. Gatewaying over IP - - In order to facilitate the gradual introduction of BLOAT into the - public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to - gateway between networks that run BLOAT natively on their LANs. - -7. DTDs - - The Transport DTDs (7.2. and 7.3.) build on the definitions in the - Network DTD (7.1.) - - The DTDs are referenced by their PubidLiteral and SystemLiteral (from - [XML]) although it is understood that most IPoXML implementations - will not need to pull down the DTD, as it will normally be embedded - in the implementation, and presents something of a catch-22 if you - need to load part of your network protocol over the network. - -7.1. IPoXML DTD - - <!-- - DTD for IP over XML. - Refer to this DTD as: - - <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> - --> - <!-- - DTD data types: - - Digits [0..9]+ - - Precedence "NetworkControl | InternetworkControl | - CRITIC | FlashOverride | Flash | Immediate | - Priority | Routine" - - IP4Addr "dotted-decimal" notation of [RFC1123] - - Class [0..3] - - Sec "Unclassified | Confidential | EFTO | MMMM | PROG | - Restricted | Secret | Top Secret | Reserved" - - Compartments [0..65535] - - Handling [0..65535] - - TCC [0..16777216] - - --> - - - -Kennedy Informational [Page 7] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - <!ENTITY % Digits "CDATA"> - <!ENTITY % Precedence "CDATA"> - <!ENTITY % IP4Addr "CDATA"> - <!ENTITY % Class "CDATA"> - <!ENTITY % Sec "CDATA"> - <!ENTITY % Compartments "CDATA"> - <!ENTITY % Handling "CDATA"> - <!ENTITY % TCC "CDATA"> - - <!ELEMENT ip (header, payload)> - - <!ELEMENT header (version, tos, total.length, id, flags, offset, ttl, - protocol, checksum, source, destination, options, - padding)> - <!-- length of header in 32-bit words --> - <!ATTLIST header - length %Digits; #REQUIRED> - - <!ELEMENT version EMPTY> - <!-- ip version. SHOULD be "4" --> - <!ATTLIST version - value %Digits; #REQUIRED> - - <!ELEMENT tos EMPTY> - <!ATTLIST tos - precedence %Precedence; #REQUIRED - delay (normal | low) #REQUIRED - throughput (normal | high) #REQUIRED - relibility (normal | high) #REQUIRED - reserved CDATA #FIXED "0"> - - <!ELEMENT total.length EMPTY> - <!-- - total length of datagram (header and payload) in octets, MUST be - less than 65,535 (and SHOULD be less than 1024 for IPoXML on local - ethernets). - --> - <!ATTLIST total.length - value %Digits; #REQUIRED> - - <!ELEMENT id EMPTY> - <!-- 0 <= id <= 65,535 --> - <!ATTLIST id - value %Digits; #REQUIRED> - - <!ELEMENT flags EMPTY> - <!-- df = don't fragment, mf = more fragments --> - <!ATTLIST flags - - - -Kennedy Informational [Page 8] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - reserved CDATA #FIXED "0" - df (may|dont) #REQUIRED - mf (last|more) #REQUIRED> - - <!ELEMENT offset EMPTY> - <!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks --> - <!ATTLIST offset - value %Digits; #REQUIRED> - - <!ELEMENT ttl EMPTY> - <!-- 0 <= ttl <= 255 --> - <!ATTLIST ttl - value %Digits; #REQUIRED> - - <!ELEMENT protocol EMPTY> - <!-- 0 <= protocol <= 255 (per IANA) --> - <!ATTLIST protocol - value %Digits; #REQUIRED> - - <!ELEMENT checksum EMPTY> - <!-- 0 <= checksum <= 65535 (over header only) --> - <!ATTLIST checksum - value %Digits; #REQUIRED> - - <!ELEMENT source EMPTY> - <!ATTLIST source - address %IP4Addr; #REQUIRED> - - <!ELEMENT destination EMPTY> - <!ATTLIST destination - address %IP4Addr; #REQUIRED> - - <!ELEMENT options ( end | noop | security | loose | strict | record - | stream | timestamp )*> - - <!ELEMENT end EMPTY> - <!ATTLIST end - copied (0|1) #REQUIRED - class CDATA #FIXED "0" - number CDATA #FIXED "0"> - - <!ELEMENT noop EMPTY> - <!ATTLIST noop - copied (0|1) #REQUIRED - class CDATA #FIXED "0" - number CDATA #FIXED "1"> - - <!ELEMENT security EMPTY> - - - -Kennedy Informational [Page 9] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - <!ATTLIST security - copied CDATA #FIXED "1" - class CDATA #FIXED "0" - number CDATA #FIXED "2" - length CDATA #FIXED "11" - security %Sec; #REQUIRED - compartments %Compartments; #REQUIRED - handling %Handling; #REQUIRED - tcc %TCC; #REQUIRED> - <!ELEMENT loose (hop)+> - <!ATTLIST loose - copied CDATA #FIXED "1" - class CDATA #FIXED "0" - number CDATA #FIXED "3" - length %Digits; #REQUIRED - pointer %Digits; #REQUIRED> - - <!ELEMENT hop EMPTY> - <!ATTLIST hop - address %IP4Addr; #REQUIRED> - - <!ELEMENT strict (hop)+> - <!ATTLIST strict - copied CDATA #FIXED "1" - class CDATA #FIXED "0" - number CDATA #FIXED "9" - length %Digits; #REQUIRED - pointer %Digits; #REQUIRED> - - <!ELEMENT record (hop)+> - <!ATTLIST record - copied CDATA #FIXED "0" - class CDATA #FIXED "0" - number CDATA #FIXED "7" - length %Digits; #REQUIRED - pointer %Digits; #REQUIRED> - - <!ELEMENT stream EMPTY> - <!-- 0 <= id <= 65,535 --> - <!ATTLIST stream - copied CDATA #FIXED "1" - class CDATA #FIXED "0" - number CDATA #FIXED "8" - length CDATA #FIXED "4" - id %Digits; #REQUIRED> - - <!ELEMENT timestamp (tstamp)+> - <!-- 0 <= oflw <=15 --> - - - -Kennedy Informational [Page 10] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - <!ATTLIST timestamp - copied CDATA #FIXED "0" - class CDATA #FIXED "2" - number CDATA #FIXED "4" - length %Digits; #REQUIRED - pointer %Digits; #REQUIRED - oflw %Digits; #REQUIRED - flag (0 | 1 | 3) #REQUIRED> - - <!ELEMENT tstamp EMPTY> - <!ATTLIST tstamp - time %Digits; #REQUIRED - address %IP4Addr; #IMPLIED> - <!-- - padding to bring header to 32-bit boundary. - pad MUST be "0"* - --> - <!ELEMENT padding EMPTY> - <!ATTLIST padding - pad CDATA #REQUIRED> - - <!-- payload MUST be encoded as base-64 [RFC2045], as modified - by section 2.1 of this RFC --> - <!ELEMENT payload (CDATA)> - -7.2. TCPoXML DTD - - <!-- - DTD for TCP over XML. - Refer to this DTD as: - - <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> - --> - - <!-- the pseudoheader is only included for checksum calculations --> - <!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)> - - <!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset, - reserved, control, window, checksum, urgent, - tcp.options, padding)> - - <!ELEMENT src EMPTY> - <!-- 0 <= port <= 65,535 --> - <!ATTLIST src - port %Digits; #REQUIRED> - - <!ELEMENT dest EMPTY> - <!-- 0 <= port <= 65,535 --> - - - -Kennedy Informational [Page 11] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - <!ATTLIST dest - port %Digits; #REQUIRED> - - <!ELEMENT sequence EMPTY> - <!-- 0 <= number <= 4294967295 --> - <!ATTLIST sequence - number %Digits; #REQUIRED> - - <!ELEMENT acknowledgement EMPTY> - <!-- 0 <= number <= 4294967295 --> - <!ATTLIST acknowledgement - number %Digits; #REQUIRED> - - <!ELEMENT offset EMPTY> - <!-- 0 <= number <= 255 --> - <!ATTLIST offset - number %Digits; #REQUIRED> - - <!ELEMENT reserved EMPTY> - <!ATTLIST reserved - value CDATA #FIXED "0"> - - <!ELEMENT control EMPTY> - <!ATTLIST control - urg (0|1) #IMPLIED - ack (0|1) #IMPLIED - psh (0|1) #IMPLIED - rst (0|1) #IMPLIED - syn (0|1) #IMPLIED - fin (0|1) #IMPLIED> - - <!ELEMENT window EMPTY> - <!-- 0 <= size <= 65,535 --> - <!ATTLIST window - size %Digits; #REQUIRED> - - <!-- - checksum as in ip, but with - the following pseudo-header added into the tcp element: - --> - <!ELEMENT tcp.pseudoheader (source, destination, protocol, - tcp.length)> - - <!-- - tcp header + data length in octets. does not include the size of - - the pseudoheader. - --> - - - -Kennedy Informational [Page 12] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - <!ELEMENT tcp.length EMPTY> - <!ATTLIST tcp.length - value %Digits; #REQUIRED> - - <!ELEMENT urgent EMPTY> - <!-- 0 <= pointer <= 65,535 --> - <!ATTLIST urgent - pointer %Digits; #REQUIRED> - - <!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+> - - <!ELEMENT tcp.end EMPTY> - <!ATTLIST tcp.end - kind CDATA #FIXED "0"> - - <!ELEMENT tcp.noop EMPTY> - <!ATTLIST tcp.noop - kind CDATA #FIXED "1"> - - <!ELEMENT tcp.mss EMPTY> - <!ATTLIST tcp.mss - kind CDATA #FIXED "2" - length CDATA #FIXED "4" - size %Digits; #REQUIRED> - -7.3. UDPoXML DTD - - <!-- - DTD for UDP over XML. - Refer to this DTD as: - - <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> - --> - - <!ELEMENT udp (udp.pseudoheader?, udp.header, payload)> - - <!ELEMENT udp.header (src, dest, udp.length, checksum)> - - <!ELEMENT udp.pseudoheader (source, destination, protocol, - udp.length)> - - <!-- - udp header + data length in octets. does not include the size of - the pseudoheader. - --> - <!ELEMENT udp.length EMPTY> - <!ATTLIST udp.length - value %Digits; #REQUIRED> - - - -Kennedy Informational [Page 13] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -8. Security Considerations - - XML, as a subset of SGML, has the same security considerations as - specified in SGML Media Types [RFC1874]. Security considerations - that apply to IP, TCP and UDP also likely apply to BLOAT as it does - not attempt to correct for issues not related to message format. - -9. References - - [JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt, - February 2002. (Work in Progress) - - [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, - August 1980. - - [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, - September 1981. - - [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC - 793, September 1981. - - [RFC894] Hornig, C., "Standard for the Transmission of IP - Datagrams over Ethernet Networks.", RFC 894, April 1984. - - [RFC1042] Postel, J. and J. Reynolds, "Standard for the - Transmission of IP Datagrams Over IEEE 802 Networks", STD - 43, RFC 1042, February 1988. - - [RFC1123] Braden, R., "Requirements for Internet Hosts - - Application and Support", RFC 1123, October 1989. - - [RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December - 1995. - - [RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, - October 1996. - - [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail - Extensions (MIME) Part One: Format of Internet Message - Bodies", RFC 2045, November 1996. - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO - 10646", RFC 2279, January 1998. - - - - - -Kennedy Informational [Page 14] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - - [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 - (IPv6) Specification", RFC 2460, December 1998. - - [RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core", - RFC 3080, March 2001. - - [SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A., - Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D., - "Simple Object Access Protocol (SOAP) 1.1" World Wide Web - Consortium Note, May 2000 http://www.w3.org/TR/SOAP/ - - [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible - Markup Language (XML)" World Wide Web Consortium - Recommendation REC- xml-19980210. - http://www.w3.org/TR/1998/REC-xml-19980210 - -10. Author's Address - - Hugh Kennedy - Mimezine - 1060 West Addison - Chicago, IL 60613 - USA - - EMail: kennedyh@engin.umich.edu - - - - - - - - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 15] - -RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 - - -11. Full Copyright Statement - - Copyright (C) The Internet Society (2002). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Kennedy Informational [Page 16] - diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 0f1f00bf6c..81d79da38b 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2022 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> @@ -37,6 +12,11 @@ #include "../shared/test_number_shared.h" +#include <QtCore/q20iterator.h> +#include <sstream> + +using namespace Qt::StringLiterals; + class tst_QByteArray : public QObject { Q_OBJECT @@ -48,13 +28,6 @@ private slots: void swap(); void qChecksum_data(); void qChecksum(); - void qCompress_data(); -#ifndef QT_NO_COMPRESS - void qCompress(); - void qUncompressCorruptedData_data(); - void qUncompressCorruptedData(); - void qCompressionZeroTermination(); -#endif void constByteArray(); void leftJustified(); void rightJustified(); @@ -78,14 +51,22 @@ private slots: void prependExtended_data(); void prependExtended(); void append(); + void appendFromRawData(); void appendExtended_data(); void appendExtended(); + void appendEmptyNull(); + void assign(); + void assignShared(); + void assignUsesPrependBuffer(); void insert(); void insertExtended_data(); void insertExtended(); void remove_data(); void remove(); + void remove_extra(); void removeIf(); + void erase(); + void erase_single_arg(); void replace_data(); void replace(); void replaceWithSpecifiedLength(); @@ -95,10 +76,10 @@ private slots: void number_double(); void number_base_data(); void number_base(); + void nullness(); void blockSizeCalculations(); void resizeAfterFromRawData(); - void appendAfterFromRawData(); void toFromHex_data(); void toFromHex(); void toFromPercentEncoding(); @@ -124,8 +105,9 @@ private slots: void reserve(); void reserveExtended_data(); void reserveExtended(); - void movablity_data(); - void movablity(); + void resize(); + void movability_data(); + void movability(); void literals(); void userDefinedLiterals(); void toUpperLower_data(); @@ -141,6 +123,8 @@ private slots: void fill(); void dataPointers(); void truncate(); + void trimmed_data(); + void trimmed(); void simplified(); void simplified_data(); void left(); @@ -148,6 +132,7 @@ private slots: void mid(); void length(); void length_data(); + void slice() const; }; static const QByteArray::DataPointer staticStandard = { @@ -161,6 +146,15 @@ static const QByteArray::DataPointer staticNotNullTerminated = { 4 }; +template <typename String> String detached(String s) +{ + if (!s.isNull()) { // detaching loses nullness, but we need to preserve it + auto d = s.data(); + Q_UNUSED(d); + } + return s; +} + template <class T> const T &verifyZeroTermination(const T &t) { return t; } QByteArray verifyZeroTermination(const QByteArray &ba) @@ -173,7 +167,7 @@ QByteArray verifyZeroTermination(const QByteArray &ba) if (!baDataPtr->isMutable()) return ba; - int baSize = ba.size(); + qsizetype baSize = ba.size(); char baTerminator = ba.constData()[baSize]; if ('\0' != baTerminator) return QString::fromUtf8( @@ -247,86 +241,13 @@ void tst_QByteArray::qChecksum() QFETCH(Qt::ChecksumType, standard); QFETCH(uint, checksum); - QCOMPARE(data.length(), int(len)); + QCOMPARE(data.size(), int(len)); if (standard == Qt::ChecksumIso3309) { QCOMPARE(::qChecksum(QByteArrayView(data.constData(), len)), static_cast<quint16>(checksum)); } QCOMPARE(::qChecksum(QByteArrayView(data.constData(), len), standard), static_cast<quint16>(checksum)); } -void tst_QByteArray::qCompress_data() -{ - QTest::addColumn<QByteArray>("ba"); - - const int size1 = 1024*1024; - QByteArray ba1( size1, 0 ); - - QTest::newRow( "00" ) << QByteArray(); - - int i; - for ( i=0; i<size1; i++ ) - ba1[i] = (char)( i / 1024 ); - QTest::newRow( "01" ) << ba1; - - for ( i=0; i<size1; i++ ) - ba1[i] = (char)( i % 256 ); - QTest::newRow( "02" ) << ba1; - - ba1.fill( 'A' ); - QTest::newRow( "03" ) << ba1; - - QFile file( QFINDTESTDATA("rfc3252.txt") ); - QVERIFY( file.open(QIODevice::ReadOnly) ); - QTest::newRow( "04" ) << file.readAll(); -} - -#ifndef QT_NO_COMPRESS -void tst_QByteArray::qCompress() -{ - QFETCH( QByteArray, ba ); - QByteArray compressed = ::qCompress( ba ); - QTEST( ::qUncompress( compressed ), "ba" ); -} - -void tst_QByteArray::qUncompressCorruptedData_data() -{ - QTest::addColumn<QByteArray>("in"); - - QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4); - QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4); - QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00", 4); - QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff", 4); - QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00", 4); - QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff", 4); - QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00", 4); - QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff", 4); - QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00", 4); - QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff", 4); - QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00", 4); - QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4); -} - -// This test is expected to produce some warning messages in the test output. -void tst_QByteArray::qUncompressCorruptedData() -{ - QFETCH(QByteArray, in); - - QByteArray res; - res = ::qUncompress(in); - QCOMPARE(res, QByteArray()); - - res = ::qUncompress(in + "blah"); - QCOMPARE(res, QByteArray()); -} - -void tst_QByteArray::qCompressionZeroTermination() -{ - QByteArray s = "Hello, I'm a string."; - QByteArray ba = ::qUncompress(::qCompress(s)); - QCOMPARE(ba.data()[ba.size()], '\0'); - QCOMPARE(ba, s); -} -#endif void tst_QByteArray::constByteArray() { @@ -517,7 +438,7 @@ void tst_QByteArray::split() QFETCH(int, size); QList<QByteArray> list = sample.split(' '); - QCOMPARE(list.count(), size); + QCOMPARE(list.size(), size); } void tst_QByteArray::swap() @@ -840,7 +761,10 @@ void tst_QByteArray::qstrncpy() // src == nullptr QCOMPARE(::qstrncpy(dst.data(), 0, 0), (char*)0); + QCOMPARE(*dst.data(), 'b'); // must not have written to dst QCOMPARE(::qstrncpy(dst.data(), 0, 10), (char*)0); + QCOMPARE(*dst.data(), '\0'); // must have written to dst + *dst.data() = 'b'; // restore // valid pointers, but len == 0 QCOMPARE(::qstrncpy(dst.data(), src.data(), 0), dst.data()); @@ -957,6 +881,7 @@ void tst_QByteArray::append() QCOMPARE(QByteArray().append(2, 'a'), QByteArray("aa")); QCOMPARE(QByteArray().append(QByteArray("data")), QByteArray("data")); QCOMPARE(QByteArray().append(data), QByteArray("data")); + QCOMPARE(QByteArray().append(data, -1), QByteArray("data")); QCOMPARE(QByteArray().append(data, 2), QByteArray("da")); QCOMPARE(QByteArray().append(QByteArrayView(data)), QByteArray("data")); @@ -1000,6 +925,20 @@ void tst_QByteArray::append() } } +void tst_QByteArray::appendFromRawData() +{ + char rawData[] = "Hello World!"; + QByteArray ba = QByteArray::fromRawData(rawData, std::size(rawData) - 1); + + QByteArray copy; + copy.append(ba); + QCOMPARE(copy, ba); + // We make an _actual_ copy, because appending a byte array + // created with fromRawData() might be optimized to copy the DataPointer, + // which means we may point to temporary stack data. + QCOMPARE_NE((void *)copy.constData(), (void *)ba.constData()); +} + void tst_QByteArray::appendExtended_data() { prependExtended_data(); @@ -1024,6 +963,207 @@ void tst_QByteArray::appendExtended() QCOMPARE(array.size(), 11); } +void tst_QByteArray::appendEmptyNull() +{ + QByteArray a; + QVERIFY(a.isEmpty()); + QVERIFY(a.isNull()); + + QByteArray b(""); + QVERIFY(b.isEmpty()); + QVERIFY(!b.isNull()); + + // Concatenating a null and an empty-but-not-null byte arrays results in + // an empty but not null byte array + QByteArray r = a + b; + QVERIFY(r.isEmpty()); + QVERIFY(!r.isNull()); +} + +void tst_QByteArray::assign() +{ + // QByteArray &assign(QByteArrayView) + { + QByteArray ba; + QByteArray test("data"); + QCOMPARE(ba.assign(test), test); + QCOMPARE(ba.size(), test.size()); + test = "data\0data"; + QCOMPARE(ba.assign(test), test); + QCOMPARE(ba.size(), test.size()); + test = "data\0data"_ba; + QCOMPARE(ba.assign(test), test); + QCOMPARE(ba.size(), test.size()); + } + // QByteArray &assign(qsizetype, char); + { + QByteArray ba; + QByteArray test("ddd"); + QCOMPARE(ba.assign(3, 'd'), test); + QCOMPARE(ba.size(), test.size()); + test = "xx"; + QCOMPARE(ba.assign(20, 'd').assign(2, 'x'), test); + QCOMPARE(ba.size(), test.size()); + test = "ddddd"; + QCOMPARE(ba.assign(0, 'x').assign(5, 'd'), test); + QCOMPARE(ba.size(), test.size()); + test = "\0\0\0"_ba; + QCOMPARE(ba.assign(0, 'x').assign(3, '\0'), test); + QCOMPARE(ba.size(), test.size()); + } + // QByteArray &assign(InputIterator, InputIterator) + { + QByteArray ba; + QByteArrayView test; + + QList<char> l = {'\0', 'T', 'E', 'S', 'T'}; + ba.assign(l.begin(), l.end()); + test = "\0TEST"_ba; + QCOMPARE(ba, test); + QCOMPARE(ba.size(), test.size()); + + const std::byte bytes[] = {std::byte('T'), std::byte(0), std::byte('S'), std::byte('T')}; + test = QByteArrayView::fromArray(bytes); + QCOMPARE(ba.assign(test.begin(), test.end()), test); + QCOMPARE(ba.size(), test.size()); + + std::stringstream ss; + ss << "T " << '\0' << ' ' << "S " << "T "; + ba.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{}); + test = "T\0ST"_ba; + QCOMPARE(ba, test); + QCOMPARE(ba.size(), test.size()); + } + // Test chaining + { + QByteArray ba; + QByteArray test("TTTTT"); + char arr[] = {'T', 'E', 'S', 'T'}; + ba.assign(std::begin(arr), std::end(arr)).assign({"Hello World!"}).assign(5, 'T'); + QCOMPARE(ba, test); + QCOMPARE(ba.size(), test.size()); + test = "DATA"; + QCOMPARE(ba.assign(300, 'T').assign({"DATA"}), test); + QCOMPARE(ba.size(), test.size()); + test = QByteArray(arr, q20::ssize(arr)); + QCOMPARE(ba.assign(10, 'c').assign(std::begin(arr), std::end(arr)), test); + QCOMPARE(ba.size(), test.size()); + test = "TTT"; + QCOMPARE(ba.assign("data").assign(QByteArrayView::fromArray( + {std::byte('T'), std::byte('T'), std::byte('T')})), test); + QCOMPARE(ba.size(), test.size()); + test = "\0data"; + QCOMPARE(ba.assign("data").assign("\0data"), test); + QCOMPARE(ba.size(), test.size()); + } +} + +void tst_QByteArray::assignShared() +{ + { + QByteArray ba; + ba.assign({"DATA"}); + QVERIFY(ba.isDetached()); + QCOMPARE(ba, QByteArray("DATA")); + + auto baCopy = ba; + QVERIFY(!ba.isDetached()); + QVERIFY(!baCopy.isDetached()); + QVERIFY(ba.isSharedWith(baCopy)); + QVERIFY(baCopy.isSharedWith(ba)); + + ba.assign(10, 'D'); + QVERIFY(ba.isDetached()); + QVERIFY(baCopy.isDetached()); + QVERIFY(!ba.isSharedWith(baCopy)); + QVERIFY(!baCopy.isSharedWith(ba)); + QCOMPARE(ba, QByteArray("DDDDDDDDDD")); + QCOMPARE(baCopy, QByteArray("DATA")); + } + { + QByteArray ba("START"); + QByteArrayView bav("DATA"); + QVERIFY(ba.isDetached()); + QCOMPARE(ba, QByteArray("START")); + + auto copyForwardIt = ba; + QVERIFY(!ba.isDetached()); + QVERIFY(!copyForwardIt.isDetached()); + QVERIFY(ba.isSharedWith(copyForwardIt)); + QVERIFY(copyForwardIt.isSharedWith(ba)); + + ba.assign(bav.begin(), bav.end()); + QVERIFY(ba.isDetached()); + QVERIFY(copyForwardIt.isDetached()); + QVERIFY(!ba.isSharedWith(copyForwardIt)); + QVERIFY(!copyForwardIt.isSharedWith(ba)); + QCOMPARE(ba, QByteArray("DATA")); + QCOMPARE(copyForwardIt, QByteArray("START")); + + auto copyInputIt = ba; + QVERIFY(!ba.isDetached()); + QVERIFY(!copyInputIt.isDetached()); + QVERIFY(ba.isSharedWith(copyInputIt)); + QVERIFY(copyInputIt.isSharedWith(ba)); + + std::stringstream ss("1 2 3 4 5 6 "); + ba.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{}); + QVERIFY(ba.isDetached()); + QVERIFY(copyInputIt.isDetached()); + QVERIFY(!ba.isSharedWith(copyInputIt)); + QVERIFY(!copyInputIt.isSharedWith(ba)); + QCOMPARE(ba, QByteArray("123456")); + QCOMPARE(copyInputIt, QByteArray("DATA")); + } +} + +void tst_QByteArray::assignUsesPrependBuffer() +{ + const auto capBegin = [](const QByteArray &ba) { + return ba.begin() - ba.d.freeSpaceAtBegin(); + }; + const auto capEnd = [](const QByteArray &ba) { + return ba.end() + ba.d.freeSpaceAtEnd(); + }; + // QByteArray &assign(QByteArrayView) + { + QByteArray withFreeSpaceAtBegin; + for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i) + withFreeSpaceAtBegin.prepend("data"); + QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1); + + const auto oldCapBegin = capBegin(withFreeSpaceAtBegin); + const auto oldCapEnd = capEnd(withFreeSpaceAtBegin); + + std::string test(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 'd'); + withFreeSpaceAtBegin.assign(test); + + QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer + QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin); + QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd); + QCOMPARE(withFreeSpaceAtBegin, test.data()); + } + // QByteArray &assign(InputIterator, InputIterator) + { + QByteArray withFreeSpaceAtBegin; + for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i) + withFreeSpaceAtBegin.prepend("data"); + QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1); + + const auto oldCapBegin = capBegin(withFreeSpaceAtBegin); + const auto oldCapEnd = capEnd(withFreeSpaceAtBegin); + + std::stringstream ss; + for (qsizetype i = 0; i < withFreeSpaceAtBegin.d.freeSpaceAtBegin(); ++i) + ss << "d "; + + withFreeSpaceAtBegin.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{}); + QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer + QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin); + QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd); + } +} + void tst_QByteArray::insert() { const char data[] = "data"; @@ -1160,7 +1300,30 @@ void tst_QByteArray::remove() QFETCH(int, position); QFETCH(int, length); QFETCH(QByteArray, expected); - QCOMPARE(src.remove(position, length), expected); + // Test when it's shared + QByteArray ba1 = src; + QCOMPARE(ba1.remove(position, length), expected); + + // Test when it's not shared + QByteArray ba2 = src; + ba2.detach(); + QCOMPARE(ba2.remove(position, length), expected); +} + +void tst_QByteArray::remove_extra() +{ + QByteArray ba = "Clock"; + ba.removeFirst(); + QCOMPARE(ba, "lock"); + ba.removeLast(); + QCOMPARE(ba, "loc"); + ba.removeAt(ba.indexOf('o')); + QCOMPARE(ba, "lc"); + ba.clear(); + // No crash on empty byte arrays + ba.removeFirst(); + ba.removeLast(); + ba.removeAt(2); } void tst_QByteArray::removeIf() @@ -1172,7 +1335,58 @@ void tst_QByteArray::removeIf() QVERIFY(!a.isDetached()); a = QByteArray("aBcAbC"); + // Test when it's not shared + QVERIFY(a.isDetached()); QCOMPARE(a.removeIf(removeA), QByteArray("BcbC")); + + a = QByteArray("aBcAbC"); + QByteArray b = a; + // Test when it's shared + QVERIFY(!b.isDetached()); + QCOMPARE(b.removeIf(removeA), QByteArray("BcbC")); +} + +void tst_QByteArray::erase() +{ + { + QByteArray ba = "kittens"; + auto it = ba.erase(ba.cbegin(), ba.cbegin() + 2); + QCOMPARE(ba, "ttens"); + QCOMPARE(it, ba.cbegin()); + } + + { + QByteArray ba = "kittens"; + auto it = ba.erase(ba.cbegin(), ba.cend()); + QCOMPARE(ba, ""); + QCOMPARE(it, ba.cbegin()); + QCOMPARE(ba.cbegin(), ba.cend()); + } + + { + QByteArray ba = "kite"; + auto it = ba.erase(ba.cbegin(), ba.cbegin()); + // erase() should return an iterator (not const_iterator) + *it = 'Z'; + QCOMPARE(ba, "Zite"); + QCOMPARE(it, ba.cbegin()); + } +} + +void tst_QByteArray::erase_single_arg() +{ + QByteArray ba = "abcdefg"; + ba.erase(ba.cend()); + auto it = ba.erase(ba.cbegin()); + QCOMPARE_EQ(ba, "bcdefg"); + QCOMPARE(it, ba.cbegin()); + + it = ba.erase(std::prev(ba.end())); + QCOMPARE_EQ(ba, "bcdef"); + QCOMPARE(it, ba.cend()); + + it = ba.erase(std::find(ba.begin(), ba.end(), QChar('d'))); + QCOMPARE(it, ba.begin() + 2); } void tst_QByteArray::replace_data() @@ -1289,7 +1503,7 @@ void tst_QByteArray::number_double_data() QTest::addRow("%s, format '%c', precision %d", title, datum.f, datum.p) << datum.d << datum.f << datum.p << ba; if (datum.f != 'f') { // Also test uppercase format - datum.f = toupper(datum.f); + datum.f = QtMiscUtils::toAsciiUpper(datum.f); QByteArray upper = ba.toUpper(); QByteArray upperTitle = QByteArray(title); if (!datum.optTitle.isEmpty()) @@ -1307,6 +1521,12 @@ void tst_QByteArray::number_double() QFETCH(double, value); QFETCH(char, format); QFETCH(int, precision); + + if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) { + if (::qstrcmp(QTest::currentDataTag(), "Very small number, very high precision, format 'f', precision 350") == 0) { + QSKIP("Skipping 'denorm' as this type lacks denormals on this system"); + } + } QTEST(QByteArray::number(value, format, precision), "expected"); } @@ -1361,6 +1581,38 @@ void tst_QByteArray::number_base() } } +void tst_QByteArray::nullness() +{ + { + QByteArray ba; + QVERIFY(ba.isNull()); + } + { + QByteArray ba = nullptr; + QVERIFY(ba.isNull()); + } + { + const char *ptr = nullptr; + QByteArray ba = ptr; + QVERIFY(ba.isNull()); + } + { + QByteArray ba(nullptr, 0); + QVERIFY(ba.isNull()); + } + { + const char *ptr = nullptr; + QByteArray ba(ptr, 0); + QVERIFY(ba.isNull()); + } + { + QByteArrayView bav; + QVERIFY(bav.isNull()); + QByteArray ba = bav.toByteArray(); + QVERIFY(ba.isNull()); + } +} + static bool checkSize(qsizetype value, qsizetype min) { return value >= min && value <= std::numeric_limits<qsizetype>::max(); @@ -1386,7 +1638,7 @@ void tst_QByteArray::blockSizeCalculations() QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2, 2, 1).elementCount, qsizetype(MaxAllocSize)/2); // error conditions - QCOMPARE(qCalculateBlockSize(qint64(MaxAllocSize) + 1, 1), qsizetype(-1)); + QCOMPARE(qCalculateBlockSize(quint64(MaxAllocSize) + 1, 1), qsizetype(-1)); QCOMPARE(qCalculateBlockSize(qsizetype(-1), 1), qsizetype(-1)); QCOMPARE(qCalculateBlockSize(MaxAllocSize, 1, 1), qsizetype(-1)); QCOMPARE(qCalculateBlockSize(MaxAllocSize/2 + 1, 2), qsizetype(-1)); @@ -1443,7 +1695,8 @@ void tst_QByteArray::blockSizeCalculations() QVERIFY(checkSize(alloc, qsizetype(MaxAllocSize) / elementSize)); // the next allocation should be invalid - QCOMPARE(qCalculateGrowingBlockSize(alloc + 1, elementSize).size, qsizetype(-1)); + if (alloc < MaxAllocSize) // lest alloc + 1 overflows (= UB) + QCOMPARE(qCalculateGrowingBlockSize(alloc + 1, elementSize).size, qsizetype(-1)); } } @@ -1459,17 +1712,6 @@ void tst_QByteArray::resizeAfterFromRawData() QVERIFY(array.constData()[5] == 0); } -void tst_QByteArray::appendAfterFromRawData() -{ - QByteArray arr; - { - char data[] = "X"; - arr += QByteArray::fromRawData(data, sizeof(data)); - data[0] = 'Y'; - } - QCOMPARE(arr.at(0), 'X'); -} - void tst_QByteArray::toFromHex_data() { QTest::addColumn<QByteArray>("str"); @@ -1549,7 +1791,7 @@ void tst_QByteArray::toFromHex_data() << QByteArray("af") << QByteArray("xaf"); - QTest::newRow("no-leading-zero") + QTest::newRow("no-leading-zero-long") << QByteArray("\xd\xde\xad\xc0\xde") << '\0' << QByteArray("0ddeadc0de") @@ -1611,15 +1853,15 @@ void tst_QByteArray::toFromPercentEncoding() QByteArray data = arr.toPercentEncoding(); QCOMPARE(data, QByteArray("Qt%20is%20great%21")); - QCOMPARE(QByteArray::fromPercentEncoding(data), arr); + QCOMPARE(data.percentDecoded(), arr); data = arr.toPercentEncoding("! ", "Qt"); QCOMPARE(data, QByteArray("%51%74 is grea%74!")); - QCOMPARE(QByteArray::fromPercentEncoding(data), arr); + QCOMPARE(data.percentDecoded(), arr); data = arr.toPercentEncoding(QByteArray(), "abcdefghijklmnopqrstuvwxyz", 'Q'); QCOMPARE(data, QByteArray("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21")); - QCOMPARE(QByteArray::fromPercentEncoding(data, 'Q'), arr); + QCOMPARE(data.percentDecoded('Q'), arr); // verify that to/from percent encoding preserves nullity arr = ""; @@ -1635,8 +1877,16 @@ void tst_QByteArray::toFromPercentEncoding() QVERIFY(arr.isNull()); QVERIFY(arr.toPercentEncoding().isEmpty()); QVERIFY(arr.toPercentEncoding().isNull()); - QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isEmpty()); - QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull()); + QVERIFY(QByteArray().percentDecoded().isEmpty()); + QVERIFY(QByteArray().percentDecoded().isNull()); + + // Verify that literal % in the string to be encoded does round-trip: + arr = "Qt%20is%20great%21"; + data = arr.toPercentEncoding(); + QCOMPARE(data.percentDecoded(), arr); + arr = "87% of all statistics are made up!"; + data = arr.toPercentEncoding(); + QCOMPARE(data.percentDecoded(), arr); } void tst_QByteArray::fromPercentEncoding_data() @@ -1658,7 +1908,7 @@ void tst_QByteArray::fromPercentEncoding() QFETCH(QByteArray, encodedString); QFETCH(QByteArray, decodedString); - QCOMPARE(QByteArray::fromPercentEncoding(encodedString), decodedString); + QCOMPARE(encodedString.percentDecoded(), decodedString); } void tst_QByteArray::toPercentEncoding_data() @@ -1719,7 +1969,7 @@ void tst_QByteArray::pecentEncodingRoundTrip() QByteArray encodedData = original.toPercentEncoding(excludeInEncoding, includeInEncoding); QCOMPARE(encodedData, encoded); - QCOMPARE(QByteArray::fromPercentEncoding(encodedData), original); + QCOMPARE(encodedData.percentDecoded(), original); } struct StringComparisonData @@ -2042,9 +2292,26 @@ void tst_QByteArray::reserveExtended() QCOMPARE(array.capacity(), array.size()); } -void tst_QByteArray::movablity_data() +void tst_QByteArray::resize() { - QTest::addColumn<QByteArray>("array"); + QByteArray ba; + ba.resize(15); + QCOMPARE(ba.size(), qsizetype(15)); + ba.resize(10); + QCOMPARE(ba.size(), 10); + ba.resize(0); + QCOMPARE(ba.size(), 0); + ba.resize(5, 'a'); + QCOMPARE(ba.size(), 5); + QCOMPARE(ba, "aaaaa"); + ba.resize(10, 'b'); + QCOMPARE(ba.size(), 10); + QCOMPARE(ba, "aaaaabbbbb"); +} + +void tst_QByteArray::movability_data() +{ + prependExtended_data(); QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4); QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4); @@ -2052,11 +2319,9 @@ void tst_QByteArray::movablity_data() QTest::newRow("empty") << QByteArray(""); QTest::newRow("null") << QByteArray(); QTest::newRow("sss") << QByteArray(3, 's'); - - prependExtended_data(); } -void tst_QByteArray::movablity() +void tst_QByteArray::movability() { QFETCH(QByteArray, array); @@ -2127,7 +2392,7 @@ void tst_QByteArray::literals() { QByteArray str(QByteArrayLiteral("abcd")); - QVERIFY(str.length() == 4); + QVERIFY(str.size() == 4); QCOMPARE(str.capacity(), 0); QVERIFY(str == "abcd"); QVERIFY(!str.data_ptr()->isMutable()); @@ -2139,34 +2404,60 @@ void tst_QByteArray::literals() // detach on non const access QVERIFY(str.data() != s); - QVERIFY(str.capacity() >= str.length()); + QVERIFY(str.capacity() >= str.size()); QVERIFY(str2.constData() == s); QVERIFY(str2.data() != s); - QVERIFY(str2.capacity() >= str2.length()); + QVERIFY(str2.capacity() >= str2.size()); } void tst_QByteArray::userDefinedLiterals() { - QByteArray str = "abcd"_qba; + { + QByteArray str = "abcd"_ba; - QVERIFY(str.length() == 4); - QCOMPARE(str.capacity(), 0); - QVERIFY(str == "abcd"); - QVERIFY(!str.data_ptr()->isMutable()); + QVERIFY(str.size() == 4); + QCOMPARE(str.capacity(), 0); + QVERIFY(str == "abcd"); + QVERIFY(!str.data_ptr()->isMutable()); - const char *s = str.constData(); - QByteArray str2 = str; - QVERIFY(str2.constData() == s); - QCOMPARE(str2.capacity(), 0); + const char *s = str.constData(); + QByteArray str2 = str; + QVERIFY(str2.constData() == s); + QCOMPARE(str2.capacity(), 0); - // detach on non const access - QVERIFY(str.data() != s); - QVERIFY(str.capacity() >= str.length()); + // detach on non const access + QVERIFY(str.data() != s); + QVERIFY(str.capacity() >= str.size()); - QVERIFY(str2.constData() == s); - QVERIFY(str2.data() != s); - QVERIFY(str2.capacity() >= str2.length()); + QVERIFY(str2.constData() == s); + QVERIFY(str2.data() != s); + QVERIFY(str2.capacity() >= str2.size()); + } + +#if QT_DEPRECATED_SINCE(6, 8) + { + QT_IGNORE_DEPRECATIONS(QByteArray str = "abcd"_qba;) + + QVERIFY(str.size() == 4); + QCOMPARE(str.capacity(), 0); + QVERIFY(str == "abcd"); + QVERIFY(!str.data_ptr()->isMutable()); + + const char *s = str.constData(); + QByteArray str2 = str; + QVERIFY(str2.constData() == s); + QCOMPARE(str2.capacity(), 0); + + // detach on non const access + QVERIFY(str.data() != s); + QVERIFY(str.capacity() >= str.size()); + + QVERIFY(str2.constData() == s); + QVERIFY(str2.data() != s); + QVERIFY(str2.capacity() >= str2.size()); + } +#endif // QT_DEPRECATED_SINCE(6, 8) } void tst_QByteArray::toUpperLower_data() @@ -2199,10 +2490,16 @@ void tst_QByteArray::toUpperLower() QFETCH(QByteArray, input); QFETCH(QByteArray, upper); QFETCH(QByteArray, lower); + QVERIFY(upper.isUpper()); + QVERIFY(lower.isLower()); QCOMPARE(lower.toLower(), lower); + QVERIFY(lower.toLower().isLower()); QCOMPARE(upper.toUpper(), upper); + QVERIFY(upper.toUpper().isUpper()); QCOMPARE(input.toUpper(), upper); + QVERIFY(input.toUpper().isUpper()); QCOMPARE(input.toLower(), lower); + QVERIFY(input.toLower().isLower()); QByteArray copy = input; QCOMPARE(std::move(copy).toUpper(), upper); @@ -2231,12 +2528,12 @@ void tst_QByteArray::toUpperLower() void tst_QByteArray::isUpper() { - QVERIFY(!QByteArray().isUpper()); - QVERIFY(!QByteArray("").isUpper()); + QVERIFY(QByteArray().isUpper()); + QVERIFY(QByteArray("").isUpper()); QVERIFY(QByteArray("TEXT").isUpper()); - QVERIFY(!QByteArray("\xD0\xDE").isUpper()); // non-ASCII is neither upper nor lower - QVERIFY(!QByteArray("\xD7").isUpper()); - QVERIFY(!QByteArray("\xDF").isUpper()); + QVERIFY(QByteArray("\xD0\xDE").isUpper()); + QVERIFY(QByteArray("\xD7").isUpper()); + QVERIFY(QByteArray("\xDF").isUpper()); QVERIFY(!QByteArray("text").isUpper()); QVERIFY(!QByteArray("Text").isUpper()); QVERIFY(!QByteArray("tExt").isUpper()); @@ -2246,19 +2543,19 @@ void tst_QByteArray::isUpper() QVERIFY(!QByteArray("teXT").isUpper()); QVERIFY(!QByteArray("tEXt").isUpper()); QVERIFY(!QByteArray("tExT").isUpper()); - QVERIFY(!QByteArray("@ABYZ[").isUpper()); + QVERIFY(QByteArray("@ABYZ[").isUpper()); QVERIFY(!QByteArray("@abyz[").isUpper()); - QVERIFY(!QByteArray("`ABYZ{").isUpper()); + QVERIFY(QByteArray("`ABYZ{").isUpper()); QVERIFY(!QByteArray("`abyz{").isUpper()); } void tst_QByteArray::isLower() { - QVERIFY(!QByteArray().isLower()); - QVERIFY(!QByteArray("").isLower()); + QVERIFY(QByteArray().isLower()); + QVERIFY(QByteArray("").isLower()); QVERIFY(QByteArray("text").isLower()); - QVERIFY(!QByteArray("\xE0\xFF").isLower()); // non-ASCII is neither upper nor lower - QVERIFY(!QByteArray("\xF7").isLower()); + QVERIFY(QByteArray("\xE0\xFF").isLower()); + QVERIFY(QByteArray("\xF7").isLower()); QVERIFY(!QByteArray("Text").isLower()); QVERIFY(!QByteArray("tExt").isLower()); QVERIFY(!QByteArray("teXt").isLower()); @@ -2269,14 +2566,14 @@ void tst_QByteArray::isLower() QVERIFY(!QByteArray("tExT").isLower()); QVERIFY(!QByteArray("TEXT").isLower()); QVERIFY(!QByteArray("@ABYZ[").isLower()); - QVERIFY(!QByteArray("@abyz[").isLower()); + QVERIFY(QByteArray("@abyz[").isLower()); QVERIFY(!QByteArray("`ABYZ{").isLower()); - QVERIFY(!QByteArray("`abyz{").isLower()); + QVERIFY(QByteArray("`abyz{").isLower()); } void tst_QByteArray::macTypes() { -#ifndef Q_OS_MAC +#ifndef Q_OS_DARWIN QSKIP("This is a Apple-only test"); #else extern void tst_QByteArray_macTypes(); // in qbytearray_mac.mm @@ -2289,7 +2586,7 @@ void tst_QByteArray::stdString() std::string stdstr( "QByteArray" ); const QByteArray stlqt = QByteArray::fromStdString(stdstr); - QCOMPARE(stlqt.length(), int(stdstr.length())); + QCOMPARE(stlqt.size(), int(stdstr.length())); QCOMPARE(stlqt.data(), stdstr.c_str()); QCOMPARE(stlqt.toStdString(), stdstr); @@ -2384,6 +2681,39 @@ void tst_QByteArray::truncate() QVERIFY(a.isEmpty()); } +void tst_QByteArray::trimmed_data() +{ + QTest::addColumn<QByteArray>("full" ); + QTest::addColumn<QByteArray>("trimmed" ); + + QTest::addRow("null") << QByteArray() << QByteArray(); + QTest::addRow("simple") << "Text"_ba << "Text"_ba; + QTest::addRow("single-space") << " "_ba << ""_ba; + QTest::addRow("single-char") << " a "_ba << "a"_ba; + QTest::addRow("mixed") << " a \n\t\v b "_ba << "a \n\t\v b"_ba; +} + +void tst_QByteArray::trimmed() +{ + QFETCH(QByteArray, full); + QFETCH(QByteArray, trimmed); + + // Shared + if (!full.isNull()) + QVERIFY(!full.isDetached()); + QCOMPARE(full.trimmed(), trimmed); // lvalue + QCOMPARE(QByteArray(full).trimmed(), trimmed); // rvalue + QCOMPARE(full.isNull(), trimmed.isNull()); + + // Not shared + full = QByteArrayView(full).toByteArray(); + if (!full.isNull()) + QVERIFY(full.isDetached()); + QCOMPARE(full.trimmed(), trimmed); // lvalue + QCOMPARE(QByteArray(full).trimmed(), trimmed); // rvalue + QCOMPARE(full.isNull(), trimmed.isNull()); +} + void tst_QByteArray::simplified() { QFETCH(QByteArray, source); @@ -2413,45 +2743,99 @@ void tst_QByteArray::simplified_data() void tst_QByteArray::left() { QByteArray a; + QCOMPARE(QByteArray().left(0), QByteArray()); + QCOMPARE(QByteArray().left(10), QByteArray()); QCOMPARE(a.left(0), QByteArray()); QCOMPARE(a.left(10), QByteArray()); QVERIFY(!a.isDetached()); + QCOMPARE(QByteArray(a).left(0), QByteArray()); + QCOMPARE(QByteArray(a).left(10), QByteArray()); + QCOMPARE(detached(a).left(0), QByteArray()); + QCOMPARE(detached(a).left(10), QByteArray()); a = QByteArray("abcdefgh"); const char *ptr = a.constData(); + + // lvalue QCOMPARE(a.left(5), QByteArray("abcde")); QCOMPARE(a.left(20), a); QCOMPARE(a.left(-5), QByteArray()); // calling left() does not modify the source array QCOMPARE(a.constData(), ptr); + + // rvalue, not detached + QCOMPARE(QByteArray(a).left(5), QByteArray("abcde")); + QCOMPARE(QByteArray(a).left(20), a); + QCOMPARE(QByteArray(a).left(-5), QByteArray()); + // calling left() does not modify the source array + QCOMPARE(a.constData(), ptr); + + // rvalue, detached + QCOMPARE(detached(a).left(5), QByteArray("abcde")); + QCOMPARE(detached(a).left(20), a); + QCOMPARE(detached(a).left(-5), QByteArray()); + // calling left() does not modify the source array + QCOMPARE(a.constData(), ptr); } void tst_QByteArray::right() { QByteArray a; + QCOMPARE(QByteArray().right(0), QByteArray()); + QCOMPARE(QByteArray().right(10), QByteArray()); QCOMPARE(a.right(0), QByteArray()); QCOMPARE(a.right(10), QByteArray()); QVERIFY(!a.isDetached()); + QCOMPARE(QByteArray(a).right(0), QByteArray()); + QCOMPARE(QByteArray(a).right(10), QByteArray()); + QCOMPARE(detached(a).right(0), QByteArray()); + QCOMPARE(detached(a).right(10), QByteArray()); a = QByteArray("abcdefgh"); const char *ptr = a.constData(); + + // lvalue QCOMPARE(a.right(5), QByteArray("defgh")); QCOMPARE(a.right(20), a); QCOMPARE(a.right(-5), QByteArray()); // calling right() does not modify the source array QCOMPARE(a.constData(), ptr); + + // rvalue, not detached + QCOMPARE(QByteArray(a).right(5), QByteArray("defgh")); + QCOMPARE(QByteArray(a).right(20), a); + QCOMPARE(QByteArray(a).right(-5), QByteArray()); + // calling right() does not modify the source array + QCOMPARE(a.constData(), ptr); + + // rvalue, detached + QCOMPARE(detached(a).right(5), QByteArray("defgh")); + QCOMPARE(detached(a).right(20), a); + QCOMPARE(detached(a).right(-5), QByteArray()); + // calling right() does not modify the source array + QCOMPARE(a.constData(), ptr); } void tst_QByteArray::mid() { QByteArray a; + QCOMPARE(QByteArray().mid(0), QByteArray()); + QCOMPARE(a.mid(0, 10), QByteArray()); QCOMPARE(a.mid(0), QByteArray()); QCOMPARE(a.mid(0, 10), QByteArray()); QCOMPARE(a.mid(10), QByteArray()); QVERIFY(!a.isDetached()); + QCOMPARE(QByteArray(a).mid(0), QByteArray()); + QCOMPARE(QByteArray(a).mid(0, 10), QByteArray()); + QCOMPARE(QByteArray(a).mid(10), QByteArray()); + QCOMPARE(detached(a).mid(0), QByteArray()); + QCOMPARE(detached(a).mid(0, 10), QByteArray()); + QCOMPARE(detached(a).mid(10), QByteArray()); a = QByteArray("abcdefgh"); const char *ptr = a.constData(); + + // lvalue QCOMPARE(a.mid(2), QByteArray("cdefgh")); QCOMPARE(a.mid(2, 3), QByteArray("cde")); QCOMPARE(a.mid(20), QByteArray()); @@ -2459,6 +2843,24 @@ void tst_QByteArray::mid() QCOMPARE(a.mid(-5, 8), QByteArray("abc")); // calling mid() does not modify the source array QCOMPARE(a.constData(), ptr); + + // rvalue, not detached + QCOMPARE(QByteArray(a).mid(2), QByteArray("cdefgh")); + QCOMPARE(QByteArray(a).mid(2, 3), QByteArray("cde")); + QCOMPARE(QByteArray(a).mid(20), QByteArray()); + QCOMPARE(QByteArray(a).mid(-5), QByteArray("abcdefgh")); + QCOMPARE(QByteArray(a).mid(-5, 8), QByteArray("abc")); + // calling mid() does not modify the source array + QCOMPARE(a.constData(), ptr); + + // rvalue, detached + QCOMPARE(detached(a).mid(2), QByteArray("cdefgh")); + QCOMPARE(detached(a).mid(2, 3), QByteArray("cde")); + QCOMPARE(detached(a).mid(20), QByteArray()); + QCOMPARE(detached(a).mid(-5), QByteArray("abcdefgh")); + QCOMPARE(detached(a).mid(-5, 8), QByteArray("abc")); + // calling mid() does not modify the source array + QCOMPARE(a.constData(), ptr); } void tst_QByteArray::length() @@ -2466,9 +2868,14 @@ void tst_QByteArray::length() QFETCH(QByteArray, src); QFETCH(qsizetype, res); - QCOMPARE(src.length(), res); QCOMPARE(src.size(), res); - QCOMPARE(src.count(), res); + QCOMPARE(src.size(), res); +#if QT_DEPRECATED_SINCE(6, 4) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + QCOMPARE(src.size(), res); +QT_WARNING_POP +#endif } void tst_QByteArray::length_data() @@ -2484,5 +2891,31 @@ void tst_QByteArray::length_data() QTest::newRow("with '\\0' no size") << QByteArray("abc\0def") << qsizetype(3); } +void tst_QByteArray::slice() const +{ + QByteArray a; + + a.slice(0); + QVERIFY(a.isEmpty()); + QVERIFY(a.isNull()); + a.slice(0, 0); + QVERIFY(a.isEmpty()); + QVERIFY(a.isNull()); + + a = "Five pineapples"; + + a.slice(5); + QCOMPARE_EQ(a, "pineapples"); + + a.slice(4, 3); + QCOMPARE_EQ(a, "app"); + + a.slice(a.size()); + QVERIFY(a.isEmpty()); + + a.slice(0, 0); + QVERIFY(a.isEmpty()); +} + QTEST_MAIN(tst_QByteArray) #include "tst_qbytearray.moc" diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm b/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm index ca8e88d4e2..a457d84b44 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm @@ -1,35 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch> -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/QByteArray> #include <QTest> +#include <QtCore/private/qcore_mac_p.h> + #include <CoreFoundation/CoreFoundation.h> #include <Foundation/Foundation.h> |