diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/restricted/uriparser/test | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/restricted/uriparser/test')
-rw-r--r-- | contrib/restricted/uriparser/test/.yandex_meta/licenses.list.txt | 1090 | ||||
-rw-r--r-- | contrib/restricted/uriparser/test/COPYING | 504 | ||||
-rw-r--r-- | contrib/restricted/uriparser/test/FourSuite.cpp | 632 | ||||
-rw-r--r-- | contrib/restricted/uriparser/test/MemoryManagerSuite.cpp | 445 | ||||
-rw-r--r-- | contrib/restricted/uriparser/test/VersionSuite.cpp | 43 | ||||
-rw-r--r-- | contrib/restricted/uriparser/test/test.cpp | 2362 | ||||
-rw-r--r-- | contrib/restricted/uriparser/test/ya.make | 38 |
7 files changed, 5114 insertions, 0 deletions
diff --git a/contrib/restricted/uriparser/test/.yandex_meta/licenses.list.txt b/contrib/restricted/uriparser/test/.yandex_meta/licenses.list.txt new file mode 100644 index 0000000000..ba9c924e51 --- /dev/null +++ b/contrib/restricted/uriparser/test/.yandex_meta/licenses.list.txt @@ -0,0 +1,1090 @@ +====================COPYRIGHT==================== + * Copyright (C) 2014, Sebastian Pipping <sebastian@pipping.org> + + +====================COPYRIGHT==================== + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + + +====================COPYRIGHT==================== +Copyright (C) 2007, Weijia Song <songweijia@gmail.com> +Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org> +All rights reserved. + + +====================COPYRIGHT==================== +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + +====================File: COPYING==================== +uriparser - RFC 3986 URI parsing library + +Copyright (C) 2007, Weijia Song <songweijia@gmail.com> +Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of + its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + + +====================File: test/COPYING==================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + + +====================LGPL-2.1-only==================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + +====================LGPL-2.1-or-later==================== + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/contrib/restricted/uriparser/test/COPYING b/contrib/restricted/uriparser/test/COPYING new file mode 100644 index 0000000000..c17622663a --- /dev/null +++ b/contrib/restricted/uriparser/test/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/contrib/restricted/uriparser/test/FourSuite.cpp b/contrib/restricted/uriparser/test/FourSuite.cpp new file mode 100644 index 0000000000..466a94cb67 --- /dev/null +++ b/contrib/restricted/uriparser/test/FourSuite.cpp @@ -0,0 +1,632 @@ +/* + * uriparser - RFC 3986 URI parsing library + * + * Copyright (C) 2007, Weijia Song <songweijia@gmail.com> + * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <gtest/gtest.h> + +#include <uriparser/Uri.h> + + + +// All testcases in this file are coming from +// http://cvs.4suite.org/viewcvs/4Suite/test/Lib/test_uri.py + + +namespace { + +bool testAddOrRemoveBaseHelper(const char * ref, const char * base, + const char * expected, bool add = true, bool domainRootMode = false) { + UriParserStateA stateA; + + // Base + UriUriA baseUri; + stateA.uri = &baseUri; + int res = uriParseUriA(&stateA, base); + if (res != 0) { + return false; + } + + // Rel + UriUriA relUri; + stateA.uri = &relUri; + res = uriParseUriA(&stateA, ref); + if (res != 0) { + uriFreeUriMembersA(&baseUri); + return false; + } + + // Expected result + UriUriA expectedUri; + stateA.uri = &expectedUri; + res = uriParseUriA(&stateA, expected); + if (res != 0) { + uriFreeUriMembersA(&baseUri); + uriFreeUriMembersA(&relUri); + uriFreeUriMembersA(&expectedUri); + return false; + } + + // Transform + UriUriA transformedUri; + if (add) { + res = uriAddBaseUriA(&transformedUri, &relUri, &baseUri); + } else { + res = uriRemoveBaseUriA(&transformedUri, &relUri, &baseUri, + domainRootMode ? URI_TRUE : URI_FALSE); + } + if (res != 0) { + uriFreeUriMembersA(&baseUri); + uriFreeUriMembersA(&relUri); + uriFreeUriMembersA(&expectedUri); + uriFreeUriMembersA(&transformedUri); + return false; + } + + const bool equal = (URI_TRUE == uriEqualsUriA(&transformedUri, &expectedUri)); + if (!equal) { + char transformedUriText[1024 * 8]; + char expectedUriText[1024 * 8]; + uriToStringA(transformedUriText, &transformedUri, 1024 * 8, NULL); + uriToStringA(expectedUriText, &expectedUri, 1024 * 8, NULL); + printf("\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", expectedUriText, transformedUriText); + } + + uriFreeUriMembersA(&baseUri); + uriFreeUriMembersA(&relUri); + uriFreeUriMembersA(&expectedUri); + uriFreeUriMembersA(&transformedUri); + return equal; +} + +} // namespace + + +TEST(FourSuite, AbsolutizeTestCases) { + const char * const BASE_URI[] = { + "http://a/b/c/d;p?q", + "http://a/b/c/d;p?q=1/2", + "http://a/b/c/d;p=1/2?q", + "fred:///s//a/b/c", + "http:///s//a/b/c"}; + + // ref, base, exptected + + // http://lists.w3.org/Archives/Public/uri/2004Feb/0114.html + ASSERT_TRUE(testAddOrRemoveBaseHelper("../c", "foo:a/b", "foo:c")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("foo:.", "foo:a", "foo:")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/foo/../../../bar", "zz:abc", "zz:/bar")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/foo/../bar", "zz:abc", "zz:/bar")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("foo/../../../bar", "zz:abc", "zz:bar")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("foo/../bar", "zz:abc", "zz:bar")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("zz:.", "zz:abc", "zz:")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/.", BASE_URI[0], "http://a/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/.foo", BASE_URI[0], "http://a/.foo")); + ASSERT_TRUE(testAddOrRemoveBaseHelper(".foo", BASE_URI[0], "http://a/b/c/.foo")); + + // http://gbiv.com/protocols/uri/test/rel_examples1.html + // examples from RFC 2396 + ASSERT_TRUE(testAddOrRemoveBaseHelper("g:h", BASE_URI[0], "g:h")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g", BASE_URI[0], "http://a/b/c/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./g", BASE_URI[0], "http://a/b/c/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/", BASE_URI[0], "http://a/b/c/g/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/g", BASE_URI[0], "http://a/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("//g", BASE_URI[0], "http://g")); + + // changed with RFC 2396bis + ASSERT_TRUE(testAddOrRemoveBaseHelper("?y", BASE_URI[0], "http://a/b/c/d;p?y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y", BASE_URI[0], "http://a/b/c/g?y")); + + // changed with RFC 2396bis + ASSERT_TRUE(testAddOrRemoveBaseHelper("#s", BASE_URI[0], "http://a/b/c/d;p?q#s")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g#s", BASE_URI[0], "http://a/b/c/g#s")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y#s", BASE_URI[0], "http://a/b/c/g?y#s")); + ASSERT_TRUE(testAddOrRemoveBaseHelper(";x", BASE_URI[0], "http://a/b/c/;x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x", BASE_URI[0], "http://a/b/c/g;x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x?y#s", BASE_URI[0], "http://a/b/c/g;x?y#s")); + + // changed with RFC 2396bis + ASSERT_TRUE(testAddOrRemoveBaseHelper("", BASE_URI[0], "http://a/b/c/d;p?q")); + ASSERT_TRUE(testAddOrRemoveBaseHelper(".", BASE_URI[0], "http://a/b/c/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./", BASE_URI[0], "http://a/b/c/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("..", BASE_URI[0], "http://a/b/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../", BASE_URI[0], "http://a/b/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../g", BASE_URI[0], "http://a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../..", BASE_URI[0], "http://a/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../", BASE_URI[0], "http://a/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../g", BASE_URI[0], "http://a/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../../g", BASE_URI[0], "http://a/g")); // http://a/../g + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../../../g", BASE_URI[0], "http://a/g")); // http://a/../../g + + // changed with RFC 2396bis + ASSERT_TRUE(testAddOrRemoveBaseHelper("/./g", BASE_URI[0], "http://a/g")); + + // changed with RFC 2396bis + ASSERT_TRUE(testAddOrRemoveBaseHelper("/../g", BASE_URI[0], "http://a/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g.", BASE_URI[0], "http://a/b/c/g.")); + ASSERT_TRUE(testAddOrRemoveBaseHelper(".g", BASE_URI[0], "http://a/b/c/.g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g..", BASE_URI[0], "http://a/b/c/g..")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("..g", BASE_URI[0], "http://a/b/c/..g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./../g", BASE_URI[0], "http://a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./g/.", BASE_URI[0], "http://a/b/c/g/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/./h", BASE_URI[0], "http://a/b/c/g/h")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/../h", BASE_URI[0], "http://a/b/c/h")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x=1/./y", BASE_URI[0], "http://a/b/c/g;x=1/y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x=1/../y", BASE_URI[0], "http://a/b/c/y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y/./x", BASE_URI[0], "http://a/b/c/g?y/./x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y/../x", BASE_URI[0], "http://a/b/c/g?y/../x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g#s/./x", BASE_URI[0], "http://a/b/c/g#s/./x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g#s/../x", BASE_URI[0], "http://a/b/c/g#s/../x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("http:g", BASE_URI[0], "http:g")); // http://a/b/c/g + ASSERT_TRUE(testAddOrRemoveBaseHelper("http:", BASE_URI[0], "http:")); // BASE_URI[0] + + // not sure where this one originated + ASSERT_TRUE(testAddOrRemoveBaseHelper("/a/b/c/./../../g", BASE_URI[0], "http://a/a/g")); + + // http://gbiv.com/protocols/uri/test/rel_examples2.html + // slashes in base URI's query args + ASSERT_TRUE(testAddOrRemoveBaseHelper("g", BASE_URI[1], "http://a/b/c/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./g", BASE_URI[1], "http://a/b/c/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/", BASE_URI[1], "http://a/b/c/g/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/g", BASE_URI[1], "http://a/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("//g", BASE_URI[1], "http://g")); + + // changed in RFC 2396bis + // ASSERT_TRUE(testAddOrRemoveBaseHelper("?y", BASE_URI[1], "http://a/b/c/?y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("?y", BASE_URI[1], "http://a/b/c/d;p?y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y", BASE_URI[1], "http://a/b/c/g?y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y/./x", BASE_URI[1], "http://a/b/c/g?y/./x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y/../x", BASE_URI[1], "http://a/b/c/g?y/../x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g#s", BASE_URI[1], "http://a/b/c/g#s")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g#s/./x", BASE_URI[1], "http://a/b/c/g#s/./x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g#s/../x", BASE_URI[1], "http://a/b/c/g#s/../x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./", BASE_URI[1], "http://a/b/c/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../", BASE_URI[1], "http://a/b/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../g", BASE_URI[1], "http://a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../", BASE_URI[1], "http://a/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../g", BASE_URI[1], "http://a/g")); + + // http://gbiv.com/protocols/uri/test/rel_examples3.html + // slashes in path params + // all of these changed in RFC 2396bis + ASSERT_TRUE(testAddOrRemoveBaseHelper("g", BASE_URI[2], "http://a/b/c/d;p=1/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./g", BASE_URI[2], "http://a/b/c/d;p=1/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/", BASE_URI[2], "http://a/b/c/d;p=1/g/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g?y", BASE_URI[2], "http://a/b/c/d;p=1/g?y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper(";x", BASE_URI[2], "http://a/b/c/d;p=1/;x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x", BASE_URI[2], "http://a/b/c/d;p=1/g;x")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x=1/./y", BASE_URI[2], "http://a/b/c/d;p=1/g;x=1/y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g;x=1/../y", BASE_URI[2], "http://a/b/c/d;p=1/y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./", BASE_URI[2], "http://a/b/c/d;p=1/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../", BASE_URI[2], "http://a/b/c/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../g", BASE_URI[2], "http://a/b/c/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../", BASE_URI[2], "http://a/b/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../g", BASE_URI[2], "http://a/b/g")); + + // http://gbiv.com/protocols/uri/test/rel_examples4.html + // double and triple slash, unknown scheme + ASSERT_TRUE(testAddOrRemoveBaseHelper("g:h", BASE_URI[3], "g:h")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g", BASE_URI[3], "fred:///s//a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./g", BASE_URI[3], "fred:///s//a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/", BASE_URI[3], "fred:///s//a/b/g/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/g", BASE_URI[3], "fred:///g")); // may change to fred:///s//a/g + ASSERT_TRUE(testAddOrRemoveBaseHelper("//g", BASE_URI[3], "fred://g")); // may change to fred:///s//g + ASSERT_TRUE(testAddOrRemoveBaseHelper("//g/x", BASE_URI[3], "fred://g/x")); // may change to fred:///s//g/x + ASSERT_TRUE(testAddOrRemoveBaseHelper("///g", BASE_URI[3], "fred:///g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./", BASE_URI[3], "fred:///s//a/b/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../", BASE_URI[3], "fred:///s//a/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../g", BASE_URI[3], "fred:///s//a/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../", BASE_URI[3], "fred:///s//")); // may change to fred:///s//a/../ + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../g", BASE_URI[3], "fred:///s//g")); // may change to fred:///s//a/../g + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../../g", BASE_URI[3], "fred:///s/g")); // may change to fred:///s//a/../../g + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../../../g", BASE_URI[3], "fred:///g")); // may change to fred:///s//a/../../../g + + // http://gbiv.com/protocols/uri/test/rel_examples5.html + // double and triple slash, well-known scheme + ASSERT_TRUE(testAddOrRemoveBaseHelper("g:h", BASE_URI[4], "g:h")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g", BASE_URI[4], "http:///s//a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./g", BASE_URI[4], "http:///s//a/b/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("g/", BASE_URI[4], "http:///s//a/b/g/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/g", BASE_URI[4], "http:///g")); // may change to http:///s//a/g + ASSERT_TRUE(testAddOrRemoveBaseHelper("//g", BASE_URI[4], "http://g")); // may change to http:///s//g + ASSERT_TRUE(testAddOrRemoveBaseHelper("//g/x", BASE_URI[4], "http://g/x")); // may change to http:///s//g/x + ASSERT_TRUE(testAddOrRemoveBaseHelper("///g", BASE_URI[4], "http:///g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./", BASE_URI[4], "http:///s//a/b/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../", BASE_URI[4], "http:///s//a/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../g", BASE_URI[4], "http:///s//a/g")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../", BASE_URI[4], "http:///s//")); // may change to http:///s//a/../ + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../g", BASE_URI[4], "http:///s//g")); // may change to http:///s//a/../g + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../../g", BASE_URI[4], "http:///s/g")); // may change to http:///s//a/../../g + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../../../g", BASE_URI[4], "http:///g")); // may change to http:///s//a/../../../g + + // from Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py + ASSERT_TRUE(testAddOrRemoveBaseHelper("bar:abc", "foo:xyz", "bar:abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../abc", "http://example/x/y/z", "http://example/x/abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("http://example/x/abc", "http://example2/x/y/z", "http://example/x/abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../r", "http://ex/x/y/z", "http://ex/x/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r", "http://ex/x/y", "http://ex/x/q/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r#s", "http://ex/x/y", "http://ex/x/q/r#s")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r#s/t", "http://ex/x/y", "http://ex/x/q/r#s/t")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("ftp://ex/x/q/r", "http://ex/x/y", "ftp://ex/x/q/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "http://ex/x/y", "http://ex/x/y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "http://ex/x/y/", "http://ex/x/y/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "http://ex/x/y/pdq", "http://ex/x/y/pdq")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("z/", "http://ex/x/y/", "http://ex/x/y/z/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("#Animal", "file:/swap/test/animal.rdf", "file:/swap/test/animal.rdf#Animal")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../abc", "file:/e/x/y/z", "file:/e/x/abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/example/x/abc", "file:/example2/x/y/z", "file:/example/x/abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../r", "file:/ex/x/y/z", "file:/ex/x/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/r", "file:/ex/x/y/z", "file:/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r", "file:/ex/x/y", "file:/ex/x/q/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r#s", "file:/ex/x/y", "file:/ex/x/q/r#s")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r#", "file:/ex/x/y", "file:/ex/x/q/r#")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q/r#s/t", "file:/ex/x/y", "file:/ex/x/q/r#s/t")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("ftp://ex/x/q/r", "file:/ex/x/y", "ftp://ex/x/q/r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "file:/ex/x/y", "file:/ex/x/y")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "file:/ex/x/y/", "file:/ex/x/y/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "file:/ex/x/y/pdq", "file:/ex/x/y/pdq")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("z/", "file:/ex/x/y/", "file:/ex/x/y/z/")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("file://meetings.example.com/cal#m1", "file:/devel/WWW/2000/10/swap/test/reluri-1.n3", "file://meetings.example.com/cal#m1")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("file://meetings.example.com/cal#m1", "file:/home/connolly/w3ccvs/WWW/2000/10/swap/test/reluri-1.n3", "file://meetings.example.com/cal#m1")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./#blort", "file:/some/dir/foo", "file:/some/dir/#blort")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./#", "file:/some/dir/foo", "file:/some/dir/#")); + + // Ryan Lee + ASSERT_TRUE(testAddOrRemoveBaseHelper("./", "http://example/x/abc.efg", "http://example/x/")); + + // Graham Klyne's tests + // http://www.ninebynine.org/Software/HaskellUtils/Network/UriTest.xls + // 01-31 are from Connelly's cases + + // 32-49 + ASSERT_TRUE(testAddOrRemoveBaseHelper("./q:r", "http://ex/x/y", "http://ex/x/q:r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./p=q:r", "http://ex/x/y", "http://ex/x/p=q:r")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("?pp/rr", "http://ex/x/y?pp/qq", "http://ex/x/y?pp/rr")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("y/z", "http://ex/x/y?pp/qq", "http://ex/x/y/z")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("local/qual@domain.org#frag", "mailto:local", "mailto:local/qual@domain.org#frag")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("more/qual2@domain2.org#frag", "mailto:local/qual1@domain1.org", "mailto:local/more/qual2@domain2.org#frag")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("y?q", "http://ex/x/y?q", "http://ex/x/y?q")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/x/y?q", "http://ex?p", "http://ex/x/y?q")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("c/d", "foo:a/b", "foo:a/c/d")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/c/d", "foo:a/b", "foo:/c/d")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("", "foo:a/b?c#d", "foo:a/b?c")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("b/c", "foo:a", "foo:b/c")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../b/c", "foo:/a/y/z", "foo:/a/b/c")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("./b/c", "foo:a", "foo:b/c")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/./b/c", "foo:a", "foo:/b/c")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../d", "foo://a//b/c", "foo://a/d")); + ASSERT_TRUE(testAddOrRemoveBaseHelper(".", "foo:a", "foo:")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("..", "foo:a", "foo:")); + + // 50-57 (cf. TimBL comments -- + // http://lists.w3.org/Archives/Public/uri/2003Feb/0028.html, + // http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html) + ASSERT_TRUE(testAddOrRemoveBaseHelper("abc", "http://example/x/y%2Fz", "http://example/x/abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../../x%2Fabc", "http://example/a/x/y/z", "http://example/a/x%2Fabc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../x%2Fabc", "http://example/a/x/y%2Fz", "http://example/a/x%2Fabc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("abc", "http://example/x%2Fy/z", "http://example/x%2Fy/abc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("q%3Ar", "http://ex/x/y", "http://ex/x/q%3Ar")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/x%2Fabc", "http://example/x/y%2Fz", "http://example/x%2Fabc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/x%2Fabc", "http://example/x/y/z", "http://example/x%2Fabc")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("/x%2Fabc", "http://example/x/y%2Fz", "http://example/x%2Fabc")); + + // 70-77 + ASSERT_TRUE(testAddOrRemoveBaseHelper("local2@domain2", "mailto:local1@domain1?query1", "mailto:local2@domain2")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("local2@domain2?query2", "mailto:local1@domain1", "mailto:local2@domain2?query2")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("local2@domain2?query2", "mailto:local1@domain1?query1", "mailto:local2@domain2?query2")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("?query2", "mailto:local@domain?query1", "mailto:local@domain?query2")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("local@domain?query2", "mailto:?query1", "mailto:local@domain?query2")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("?query2", "mailto:local@domain?query1", "mailto:local@domain?query2")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("http://example/a/b?c/../d", "foo:bar", "http://example/a/b?c/../d")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("http://example/a/b#c/../d", "foo:bar", "http://example/a/b#c/../d")); + + // 82-88 + ASSERT_TRUE(testAddOrRemoveBaseHelper("http:this", "http://example.org/base/uri", "http:this")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("http:this", "http:base", "http:this")); + // Whole in the URI spec, see http://lists.w3.org/Archives/Public/uri/2007Aug/0003.html + // ASSERT_TRUE(testAddOrRemoveBaseHelper(".//g", "f:/a", "f://g")); // ORIGINAL + ASSERT_TRUE(testAddOrRemoveBaseHelper(".//g", "f:/a", "f:/.//g")); // FIXED ONE + ASSERT_TRUE(testAddOrRemoveBaseHelper("b/c//d/e", "f://example.org/base/a", "f://example.org/base/b/c//d/e")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("m2@example.ord/c2@example.org", "mid:m@example.ord/c@example.org", "mid:m@example.ord/m2@example.ord/c2@example.org")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("mini1.xml", "file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/", "file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/mini1.xml")); + ASSERT_TRUE(testAddOrRemoveBaseHelper("../b/c", "foo:a/y/z", "foo:a/b/c")); +} + + + +TEST(FourSuite, RelativizeTestCases) { + const bool REMOVE_MODE = false; + const bool DOMAIN_ROOT_MODE = true; + + // to convert, base, exptected + + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/a/d", "b/c", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/b/b/c", "s://ex/a/d", "/b/b/c", REMOVE_MODE, DOMAIN_ROOT_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/a/b/", "c", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://other.ex/a/b/", "s://ex/a/d", "//other.ex/a/b/", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://other.ex/a/d", "//ex/a/b/c", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("t://ex/a/b/c", "s://ex/a/d", "t://ex/a/b/c", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c", "t://ex/a/d", "s://ex/a/b/c", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a", "s://ex/b/c/d", "/a", REMOVE_MODE, DOMAIN_ROOT_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/b/c/d", "s://ex/a", "b/c/d", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c?h", "s://ex/a/d?w", "b/c?h", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c#h", "s://ex/a/d#w", "b/c#h", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c?h#i", "s://ex/a/d?w#j", "b/c?h#i", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a#i", "s://ex/a", "#i", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a?i", "s://ex/a", "?i", REMOVE_MODE)); + + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/", "s://ex/a/b/", "", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b", "s://ex/a/b", "", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/", "s://ex/", "", REMOVE_MODE)); + + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/a/d/c", "../b/c", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c/", "s://ex/a/d/c", "../b/c/", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c/d", "s://ex/a/d/c/d", "../../b/c/d", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/c", "s://ex/d/e/f", "/a/b/c", REMOVE_MODE, DOMAIN_ROOT_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b/", "s://ex/a/c/d/e", "../../b/", REMOVE_MODE)); + + // Some tests to ensure that empty path segments don't cause problems. + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/b", "s://ex/a//b/c", "../../b", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a///b", "s://ex/a/", ".///b", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a/", "s://ex/a///b", "../../", REMOVE_MODE)); + ASSERT_TRUE(testAddOrRemoveBaseHelper("s://ex/a//b/c", "s://ex/a/b", ".//b/c", REMOVE_MODE)); +} + + +namespace { + +int testParseUri(const char * uriText, const char ** expectedErrorPos = NULL) { + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + int res = uriParseUriA(&state, uriText); + if (expectedErrorPos != NULL) { + *expectedErrorPos = state.errorPos; + } + uriFreeUriMembersA(&uri); + return res; +} + + + +bool testGoodUri(const char * uriText) { + return (testParseUri(uriText) == 0); +} + + + +bool testBadUri(const char * uriText, int expectedErrorOffset = -1) { + const char * errorPos = NULL; + const int ret = testParseUri(uriText, &errorPos); + return ((ret == URI_ERROR_SYNTAX) + && (errorPos != NULL) + && ( + (expectedErrorOffset == -1) + || (errorPos == (uriText + expectedErrorOffset)) + )); +} + +} // namespace + + + +TEST(FourSuite, GoodUriReferences) { + ASSERT_TRUE(testGoodUri("file:///foo/bar")); + ASSERT_TRUE(testGoodUri("mailto:user@host?subject=blah")); + ASSERT_TRUE(testGoodUri("dav:")); // empty opaque part / rel-path allowed by RFC 2396bis + ASSERT_TRUE(testGoodUri("about:")); // empty opaque part / rel-path allowed by RFC 2396bis + + // the following test cases are from a Perl script by David A. Wheeler + // at http://www.dwheeler.com/secure-programs/url.pl + ASSERT_TRUE(testGoodUri("http://www.yahoo.com")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/")); + ASSERT_TRUE(testGoodUri("http://1.2.3.4/")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/stuff")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/stuff/")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/hello%20world/")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com?name=obi")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com?name=obi+wan&status=jedi")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com?onery")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com#bottom")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/yelp.html#bottom")); + ASSERT_TRUE(testGoodUri("https://www.yahoo.com/")); + ASSERT_TRUE(testGoodUri("ftp://www.yahoo.com/")); + ASSERT_TRUE(testGoodUri("ftp://www.yahoo.com/hello")); + ASSERT_TRUE(testGoodUri("demo.txt")); + ASSERT_TRUE(testGoodUri("demo/hello.txt")); + ASSERT_TRUE(testGoodUri("demo/hello.txt?query=hello#fragment")); + ASSERT_TRUE(testGoodUri("/cgi-bin/query?query=hello#fragment")); + ASSERT_TRUE(testGoodUri("/demo.txt")); + ASSERT_TRUE(testGoodUri("/hello/demo.txt")); + ASSERT_TRUE(testGoodUri("hello/demo.txt")); + ASSERT_TRUE(testGoodUri("/")); + ASSERT_TRUE(testGoodUri("")); + ASSERT_TRUE(testGoodUri("#")); + ASSERT_TRUE(testGoodUri("#here")); + + // Wheeler's script says these are invalid, but they aren't + ASSERT_TRUE(testGoodUri("http://www.yahoo.com?name=%00%01")); + ASSERT_TRUE(testGoodUri("http://www.yaho%6f.com")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/hello%00world/")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/hello+world/")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com?name=obi&")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com?name=obi&type=")); + ASSERT_TRUE(testGoodUri("http://www.yahoo.com/yelp.html#")); + ASSERT_TRUE(testGoodUri("//")); + + // the following test cases are from a Haskell program by Graham Klyne + // at http://www.ninebynine.org/Software/HaskellUtils/Network/URITest.hs + ASSERT_TRUE(testGoodUri("http://example.org/aaa/bbb#ccc")); + ASSERT_TRUE(testGoodUri("mailto:local@domain.org")); + ASSERT_TRUE(testGoodUri("mailto:local@domain.org#frag")); + ASSERT_TRUE(testGoodUri("HTTP://EXAMPLE.ORG/AAA/BBB#CCC")); + ASSERT_TRUE(testGoodUri("//example.org/aaa/bbb#ccc")); + ASSERT_TRUE(testGoodUri("/aaa/bbb#ccc")); + ASSERT_TRUE(testGoodUri("bbb#ccc")); + ASSERT_TRUE(testGoodUri("#ccc")); + ASSERT_TRUE(testGoodUri("#")); + ASSERT_TRUE(testGoodUri("A'C")); + + // escapes + ASSERT_TRUE(testGoodUri("http://example.org/aaa%2fbbb#ccc")); + ASSERT_TRUE(testGoodUri("http://example.org/aaa%2Fbbb#ccc")); + ASSERT_TRUE(testGoodUri("%2F")); + ASSERT_TRUE(testGoodUri("aaa%2Fbbb")); + + // ports + ASSERT_TRUE(testGoodUri("http://example.org:80/aaa/bbb#ccc")); + ASSERT_TRUE(testGoodUri("http://example.org:/aaa/bbb#ccc")); + ASSERT_TRUE(testGoodUri("http://example.org./aaa/bbb#ccc")); + ASSERT_TRUE(testGoodUri("http://example.123./aaa/bbb#ccc")); + + // bare authority + ASSERT_TRUE(testGoodUri("http://example.org")); + + // IPv6 literals (from RFC2732): + ASSERT_TRUE(testGoodUri("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html")); + ASSERT_TRUE(testGoodUri("http://[1080:0:0:0:8:800:200C:417A]/index.html")); + ASSERT_TRUE(testGoodUri("http://[3ffe:2a00:100:7031::1]")); + ASSERT_TRUE(testGoodUri("http://[1080::8:800:200C:417A]/foo")); + ASSERT_TRUE(testGoodUri("http://[::192.9.5.5]/ipng")); + ASSERT_TRUE(testGoodUri("http://[::FFFF:129.144.52.38]:80/index.html")); + ASSERT_TRUE(testGoodUri("http://[2010:836B:4179::836B:4179]")); + ASSERT_TRUE(testGoodUri("//[2010:836B:4179::836B:4179]")); + + // Random other things that crop up + ASSERT_TRUE(testGoodUri("http://example/Andrȷ")); + ASSERT_TRUE(testGoodUri("file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/")); +} + + + +TEST(FourSuite, BadUriReferences) { + ASSERT_TRUE(testBadUri("beepbeep\x07\x07", 8)); + ASSERT_TRUE(testBadUri("\n", 0)); + ASSERT_TRUE(testBadUri("::", 0)); // not OK, per Roy Fielding on the W3C uri list on 2004-04-01 + + // the following test cases are from a Perl script by David A. Wheeler + // at http://www.dwheeler.com/secure-programs/url.pl + ASSERT_TRUE(testBadUri("http://www yahoo.com", 10)); + ASSERT_TRUE(testBadUri("http://www.yahoo.com/hello world/", 26)); + ASSERT_TRUE(testBadUri("http://www.yahoo.com/yelp.html#\"", 31)); + + // the following test cases are from a Haskell program by Graham Klyne + // at http://www.ninebynine.org/Software/HaskellUtils/Network/URITest.hs + ASSERT_TRUE(testBadUri("[2010:836B:4179::836B:4179]", 0)); + ASSERT_TRUE(testBadUri(" ", 0)); + ASSERT_TRUE(testBadUri("%", 1)); + ASSERT_TRUE(testBadUri("A%Z", 2)); + ASSERT_TRUE(testBadUri("%ZZ", 1)); + ASSERT_TRUE(testBadUri("%AZ", 2)); + ASSERT_TRUE(testBadUri("A C", 1)); + ASSERT_TRUE(testBadUri("A\\'C", 1)); // r"A\'C" + ASSERT_TRUE(testBadUri("A`C", 1)); + ASSERT_TRUE(testBadUri("A<C", 1)); + ASSERT_TRUE(testBadUri("A>C", 1)); + ASSERT_TRUE(testBadUri("A^C", 1)); + ASSERT_TRUE(testBadUri("A\\\\C", 1)); // r'A\\C' + ASSERT_TRUE(testBadUri("A{C", 1)); + ASSERT_TRUE(testBadUri("A|C", 1)); + ASSERT_TRUE(testBadUri("A}C", 1)); + ASSERT_TRUE(testBadUri("A[C", 1)); + ASSERT_TRUE(testBadUri("A]C", 1)); + ASSERT_TRUE(testBadUri("A[**]C", 1)); + ASSERT_TRUE(testBadUri("http://[xyz]/", 8)); + ASSERT_TRUE(testBadUri("http://]/", 7)); + ASSERT_TRUE(testBadUri("http://example.org/[2010:836B:4179::836B:4179]", 19)); + ASSERT_TRUE(testBadUri("http://example.org/abc#[2010:836B:4179::836B:4179]", 23)); + ASSERT_TRUE(testBadUri("http://example.org/xxx/[qwerty]#a[b]", 23)); + + // from a post to the W3C uri list on 2004-02-17 + // breaks at 22 instead of 17 because everything up to that point is a valid userinfo + ASSERT_TRUE(testBadUri("http://w3c.org:80path1/path2", 22)); +} + + + +namespace { + +bool normalizeAndCompare(const char * uriText, + const char * expectedNormalized) { + UriParserStateA stateA; + int res; + + UriUriA testUri; + stateA.uri = &testUri; + res = uriParseUriA(&stateA, uriText); + if (res != 0) { + uriFreeUriMembersA(&testUri); + return false; + } + + // Expected result + UriUriA expectedUri; + stateA.uri = &expectedUri; + res = uriParseUriA(&stateA, expectedNormalized); + if (res != 0) { + uriFreeUriMembersA(&testUri); + uriFreeUriMembersA(&expectedUri); + return false; + } + + res = uriNormalizeSyntaxA(&testUri); + if (res != 0) { + uriFreeUriMembersA(&testUri); + uriFreeUriMembersA(&expectedUri); + return false; + } + + const bool equalAfter = (URI_TRUE == uriEqualsUriA(&testUri, &expectedUri)); + uriFreeUriMembersA(&testUri); + uriFreeUriMembersA(&expectedUri); + return equalAfter; +} + +} // namespace + + + +TEST(FourSuite, CaseNormalizationTests) { + ASSERT_TRUE(normalizeAndCompare("HTTP://www.EXAMPLE.com/", "http://www.example.com/")); + ASSERT_TRUE(normalizeAndCompare("example://A/b/c/%7bfoo%7d", "example://a/b/c/%7Bfoo%7D")); +} + + + +TEST(FourSuite, PctEncNormalizationTests) { + ASSERT_TRUE(normalizeAndCompare("http://host/%7Euser/x/y/z", "http://host/~user/x/y/z")); + ASSERT_TRUE(normalizeAndCompare("http://host/%7euser/x/y/z", "http://host/~user/x/y/z")); +} + + + +TEST(FourSuite, PathSegmentNormalizationTests) { + ASSERT_TRUE(normalizeAndCompare("/a/b/../../c", "/c")); + // ASSERT_TRUE(normalizeAndCompare("a/b/../../c", "a/b/../../c")); + // Fixed: + ASSERT_TRUE(normalizeAndCompare("a/b/../../c", "c")); + ASSERT_TRUE(normalizeAndCompare("/a/b/././c", "/a/b/c")); + // ASSERT_TRUE(normalizeAndCompare("a/b/././c", "a/b/././c")); + // Fixed: + ASSERT_TRUE(normalizeAndCompare("a/b/././c", "a/b/c")); + ASSERT_TRUE(normalizeAndCompare("/a/b/../c/././d", "/a/c/d")); + // ASSERT_TRUE(normalizeAndCompare("a/b/../c/././d", "a/b/../c/././d")); + // Fixed: + ASSERT_TRUE(normalizeAndCompare("a/b/../c/././d", "a/c/d")); +} diff --git a/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp b/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp new file mode 100644 index 0000000000..0abc263bca --- /dev/null +++ b/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp @@ -0,0 +1,445 @@ +/* + * uriparser - RFC 3986 URI parsing library + * + * Copyright (C) 2007, Weijia Song <songweijia@gmail.com> + * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#undef NDEBUG // because we rely on assert(3) further down + +#include <cassert> +#include <cerrno> +#include <cstring> // memcpy +#include <gtest/gtest.h> + +#include <uriparser/Uri.h> + +// For defaultMemoryManager +extern "C" { +#include "../src/UriMemory.h" +} + + +namespace { + + + +static void * failingMalloc(UriMemoryManager * memory, size_t size); +static void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size); +static void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size); +static void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size); +static void countingFree(UriMemoryManager * memory, void * ptr); + + + +class FailingMemoryManager { +private: + UriMemoryManager memoryManager; + unsigned int callCountAlloc; + unsigned int callCountFree; + unsigned int failAllocAfterTimes; + + friend void * failingMalloc(UriMemoryManager * memory, size_t size); + friend void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size); + friend void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size); + friend void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size); + friend void countingFree(UriMemoryManager * memory, void * ptr); + +public: + FailingMemoryManager(unsigned int failAllocAfterTimes = 0) + : callCountAlloc(0), callCountFree(0), + failAllocAfterTimes(failAllocAfterTimes) { + this->memoryManager.malloc = failingMalloc; + this->memoryManager.calloc = failingCalloc; + this->memoryManager.realloc = failingRealloc; + this->memoryManager.reallocarray = failingReallocarray; + this->memoryManager.free = countingFree; + this->memoryManager.userData = this; + } + + UriMemoryManager * operator&() { + return &(this->memoryManager); + } + + unsigned int getCallCountFree() const { + return this->callCountFree; + } +}; + + + +static void * failingMalloc(UriMemoryManager * memory, size_t size) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountAlloc++; + if (fmm->callCountAlloc > fmm->failAllocAfterTimes) { + errno = ENOMEM; + return NULL; + } + return malloc(size); +} + + + +static void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountAlloc++; + if (fmm->callCountAlloc > fmm->failAllocAfterTimes) { + errno = ENOMEM; + return NULL; + } + return calloc(nmemb, size); +} + + + +static void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountAlloc++; + if (fmm->callCountAlloc > fmm->failAllocAfterTimes) { + errno = ENOMEM; + return NULL; + } + return realloc(ptr, size); +} + + + +static void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size) { + return uriEmulateReallocarray(memory, ptr, nmemb, size); +} + + + +static void countingFree(UriMemoryManager * memory, void * ptr) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountFree++; + return free(ptr); +} + + + +static UriUriA parse(const char * sourceUriString) { + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + assert(uriParseUriA(&state, sourceUriString) == URI_SUCCESS); + return uri; +} + + + +static UriQueryListA * parseQueryList(const char * queryString) { + UriQueryListA * queryList; + const char * const first = queryString; + const char * const afterLast = first + strlen(first); + assert(uriDissectQueryMallocA(&queryList, NULL, first, afterLast) + == URI_SUCCESS); + return queryList; +} + +} // namespace + + + +TEST(MemoryManagerCompletenessSuite, AllFunctionMembersRequired) { + UriUriA uri = parse("whatever"); + UriMemoryManager memory; + + memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager)); + memory.malloc = NULL; + ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); + + memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager)); + memory.calloc = NULL; + ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); + + memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager)); + memory.realloc = NULL; + ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); + + memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager)); + memory.reallocarray = NULL; + ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); + + memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager)); + memory.free = NULL; + ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); + + memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager)); + ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), URI_SUCCESS); +} + + + +TEST(MemoryManagerCompletenessSuite, MallocAndFreeRequiredOnly) { + UriMemoryManager memory; + UriMemoryManager backend; + + memcpy(&backend, &defaultMemoryManager, sizeof(UriMemoryManager)); + backend.malloc = NULL; + ASSERT_EQ(uriCompleteMemoryManager(&memory, &backend), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); + + memcpy(&backend, &defaultMemoryManager, sizeof(UriMemoryManager)); + backend.free = NULL; + ASSERT_EQ(uriCompleteMemoryManager(&memory, &backend), + URI_ERROR_MEMORY_MANAGER_INCOMPLETE); +} + + + +TEST(MemoryManagerTestingSuite, DISABLED_DefaultMemoryManager) { + ASSERT_EQ(uriTestMemoryManager(&defaultMemoryManager), URI_SUCCESS); +} + + + +TEST(MemoryManagerTestingSuite, CompleteMemoryManager) { + UriMemoryManager memory; + UriMemoryManager backend; + + memset(&backend, 0, sizeof(UriMemoryManager)); + backend.malloc = defaultMemoryManager.malloc; + backend.free = defaultMemoryManager.free; + + ASSERT_EQ(uriCompleteMemoryManager(&memory, &backend), + URI_SUCCESS); + + ASSERT_EQ(uriTestMemoryManager(&memory), URI_SUCCESS); +} + + + +TEST(MemoryManagerTestingSuite, DISABLED_EmulateCalloc) { + UriMemoryManager partialEmulationMemoryManager; + memcpy(&partialEmulationMemoryManager, &defaultMemoryManager, + sizeof(UriMemoryManager)); + partialEmulationMemoryManager.calloc = uriEmulateCalloc; + + ASSERT_EQ(uriTestMemoryManager(&partialEmulationMemoryManager), + URI_SUCCESS); +} + + + +TEST(MemoryManagerTestingSuite, EmulateReallocarray) { + UriMemoryManager partialEmulationMemoryManager; + memcpy(&partialEmulationMemoryManager, &defaultMemoryManager, + sizeof(UriMemoryManager)); + partialEmulationMemoryManager.reallocarray = uriEmulateReallocarray; + + ASSERT_EQ(uriTestMemoryManager(&partialEmulationMemoryManager), + URI_SUCCESS); +} + + + +TEST(MemoryManagerTestingOverflowDetectionSuite, EmulateCalloc) { + EXPECT_GT(2 * sizeof(size_t), sizeof(void *)); + + errno = 0; + ASSERT_EQ(NULL, uriEmulateCalloc( + &defaultMemoryManager, (size_t)-1, (size_t)-1)); + ASSERT_EQ(errno, ENOMEM); +} + + + +TEST(MemoryManagerTestingOverflowDetectionSuite, EmulateReallocarray) { + EXPECT_GT(2 * sizeof(size_t), sizeof(void *)); + + errno = 0; + ASSERT_EQ(NULL, uriEmulateReallocarray( + &defaultMemoryManager, NULL, (size_t)-1, (size_t)-1)); + ASSERT_EQ(errno, ENOMEM); +} + + + +TEST(MemoryManagerTestingSuite, EmulateCallocAndReallocarray) { + UriMemoryManager partialEmulationMemoryManager; + memcpy(&partialEmulationMemoryManager, &defaultMemoryManager, + sizeof(UriMemoryManager)); + partialEmulationMemoryManager.calloc = uriEmulateCalloc; + partialEmulationMemoryManager.reallocarray = uriEmulateReallocarray; + + ASSERT_EQ(uriTestMemoryManager(&partialEmulationMemoryManager), + URI_SUCCESS); +} + + + +TEST(FailingMemoryManagerSuite, AddBaseUriExMm) { + UriUriA absoluteDest; + UriUriA relativeSource = parse("foo"); + UriUriA absoluteBase = parse("http://example.org/bar"); + const UriResolutionOptions options = URI_RESOLVE_STRICTLY; + FailingMemoryManager failingMemoryManager; + + ASSERT_EQ(uriAddBaseUriExMmA(&absoluteDest, &relativeSource, + &absoluteBase, options, &failingMemoryManager), + URI_ERROR_MALLOC); + + uriFreeUriMembersA(&relativeSource); + uriFreeUriMembersA(&absoluteBase); +} + + + +TEST(FailingMemoryManagerSuite, ComposeQueryMallocExMm) { + char * dest = NULL; + UriQueryListA * const queryList = parseQueryList("k1=v1"); + UriBool spaceToPlus = URI_TRUE; // not of interest + UriBool normalizeBreaks = URI_TRUE; // not of interest + FailingMemoryManager failingMemoryManager; + + ASSERT_EQ(uriComposeQueryMallocExMmA(&dest, queryList, + spaceToPlus, normalizeBreaks, &failingMemoryManager), + URI_ERROR_MALLOC); + + uriFreeQueryListA(queryList); +} + + + +TEST(FailingMemoryManagerSuite, DissectQueryMallocExMm) { + UriQueryListA * queryList; + int itemCount; + const char * const first = "k1=v1&k2=v2"; + const char * const afterLast = first + strlen(first); + const UriBool plusToSpace = URI_TRUE; // not of interest + const UriBreakConversion breakConversion = URI_BR_DONT_TOUCH; // not o. i. + FailingMemoryManager failingMemoryManager; + + ASSERT_EQ(uriDissectQueryMallocExMmA(&queryList, &itemCount, + first, afterLast, plusToSpace, breakConversion, + &failingMemoryManager), + URI_ERROR_MALLOC); +} + + + +TEST(FailingMemoryManagerSuite, FreeQueryListMm) { + UriQueryListA * const queryList = parseQueryList("k1=v1"); + FailingMemoryManager failingMemoryManager; + ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0U); + + uriFreeQueryListMmA(queryList, &failingMemoryManager); + + ASSERT_GE(failingMemoryManager.getCallCountFree(), 1U); +} + + + +TEST(FailingMemoryManagerSuite, FreeUriMembersMm) { + UriUriA uri = parse("http://example.org/"); + FailingMemoryManager failingMemoryManager; + ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0U); + + uriFreeUriMembersMmA(&uri, &failingMemoryManager); + + ASSERT_GE(failingMemoryManager.getCallCountFree(), 1U); + uriFreeUriMembersA(&uri); +} + +namespace { + void testNormalizeSyntaxWithFailingMallocCallsFreeTimes(const char * uriString, + unsigned int mask, + unsigned int failAllocAfterTimes = 0, + unsigned int expectedCallCountFree = 0) { + UriUriA uri = parse(uriString); + FailingMemoryManager failingMemoryManager(failAllocAfterTimes); + + ASSERT_EQ(uriNormalizeSyntaxExMmA(&uri, mask, &failingMemoryManager), + URI_ERROR_MALLOC); + + EXPECT_EQ(failingMemoryManager.getCallCountFree(), expectedCallCountFree); + + uriFreeUriMembersA(&uri); + } +} // namespace + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmScheme) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("hTTp://example.org/path", URI_NORMALIZE_SCHEME); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyUserInfo) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//@:123", URI_NORMALIZE_USER_INFO); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyHostRegname) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123", URI_NORMALIZE_HOST); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyQuery) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123?", URI_NORMALIZE_QUERY); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyFragment) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123#", URI_NORMALIZE_FRAGMENT); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextIp4) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//192.0.2.0:123" /* RFC 5737 */, URI_NORMALIZE_HOST, 1, 1); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextIp6) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//[2001:db8::]:123" /* RFC 3849 */, URI_NORMALIZE_HOST, 1, 1); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextRegname) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//host123.test:123" /* RFC 6761 */, URI_NORMALIZE_HOST, 1, 1); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextFuture) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//[v7.X]:123" /* arbitrary IPvFuture */, URI_NORMALIZE_HOST, 1, 1); +} + + + +TEST(FailingMemoryManagerSuite, ParseSingleUriExMm) { + UriUriA uri; + const char * const first = "k1=v1&k2=v2"; + const char * const afterLast = first + strlen(first); + FailingMemoryManager failingMemoryManager; + + ASSERT_EQ(uriParseSingleUriExMmA(&uri, first, afterLast, NULL, + &failingMemoryManager), + URI_ERROR_MALLOC); +} + + + +TEST(FailingMemoryManagerSuite, RemoveBaseUriMm) { + UriUriA dest; + UriUriA absoluteSource = parse("http://example.org/a/b/c/"); + UriUriA absoluteBase = parse("http://example.org/a/"); + const UriBool domainRootMode = URI_TRUE; // not of interest + FailingMemoryManager failingMemoryManager; + + ASSERT_EQ(uriRemoveBaseUriMmA(&dest, &absoluteSource, &absoluteBase, + domainRootMode, &failingMemoryManager), + URI_ERROR_MALLOC); + + uriFreeUriMembersA(&absoluteSource); + uriFreeUriMembersA(&absoluteBase); +} diff --git a/contrib/restricted/uriparser/test/VersionSuite.cpp b/contrib/restricted/uriparser/test/VersionSuite.cpp new file mode 100644 index 0000000000..a46f0d59b3 --- /dev/null +++ b/contrib/restricted/uriparser/test/VersionSuite.cpp @@ -0,0 +1,43 @@ +/* + * uriparser - RFC 3986 URI parsing library + * + * Copyright (C) 2014, Sebastian Pipping <sebastian@pipping.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <gtest/gtest.h> + +#include <cstdio> + + +#include <config.h> // for PACKAGE_VERSION +#include <uriparser/UriBase.h> + + +TEST(VersionSuite, EnsureVersionDefinesInSync) { + char INSIDE_VERSION[256]; + const int bytes_printed = sprintf(INSIDE_VERSION, "%d.%d.%d%s", + URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, URI_VER_SUFFIX_ANSI); + ASSERT_TRUE(bytes_printed != -1); + + const bool equal = !strcmp(INSIDE_VERSION, PACKAGE_VERSION); + if (! equal) { + printf("Inside/outside version mismatch detected:\n"); + printf(" Tarball version: <%s>\n", PACKAGE_VERSION); + printf(" Header defines version: <%s>\n", INSIDE_VERSION); + } + ASSERT_TRUE(equal); +} diff --git a/contrib/restricted/uriparser/test/test.cpp b/contrib/restricted/uriparser/test/test.cpp new file mode 100644 index 0000000000..8580399733 --- /dev/null +++ b/contrib/restricted/uriparser/test/test.cpp @@ -0,0 +1,2362 @@ +/* + * uriparser - RFC 3986 URI parsing library + * + * Copyright (C) 2007, Weijia Song <songweijia@gmail.com> + * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <uriparser/Uri.h> +#include <uriparser/UriIp4.h> +#include <gtest/gtest.h> +#include <memory> +#include <cstdio> +#include <cstdlib> +#include <cwchar> + +using namespace std; + + + +extern "C" { +UriBool uri_TESTING_ONLY_ParseIpSixA(const char * text); +UriBool uri_TESTING_ONLY_ParseIpFourA(const char * text); +int uriCompareRangeA(const UriTextRangeA * a, const UriTextRangeA * b); +} + + + +#define URI_TEST_IP_FOUR_FAIL(x) ASSERT_TRUE(URI_FALSE == uri_TESTING_ONLY_ParseIpFourA(x)) +#define URI_TEST_IP_FOUR_PASS(x) ASSERT_TRUE(URI_TRUE == uri_TESTING_ONLY_ParseIpFourA(x)) + +// Note the closing brackets! TODO +#define URI_TEST_IP_SIX_FAIL(x) ASSERT_TRUE(URI_FALSE == uri_TESTING_ONLY_ParseIpSixA(x "]")) +#define URI_TEST_IP_SIX_PASS(x) ASSERT_TRUE(URI_TRUE == uri_TESTING_ONLY_ParseIpSixA(x "]")) + +#define URI_EXPECT_BETWEEN(candidate, first, afterLast) \ + EXPECT_TRUE((candidate >= first) && (candidate <= afterLast)) + +#define URI_EXPECT_OUTSIDE(candidate, first, afterLast) \ + EXPECT_TRUE((candidate < first) || (candidate > afterLast)) + +#define URI_EXPECT_RANGE_BETWEEN(range, uriFirst, uriAfterLast) \ + URI_EXPECT_BETWEEN(range.first, uriFirst, uriAfterLast); \ + URI_EXPECT_BETWEEN(range.afterLast, uriFirst, uriAfterLast) + +#define URI_EXPECT_RANGE_OUTSIDE(range, uriFirst, uriAfterLast) \ + URI_EXPECT_OUTSIDE(range.first, uriFirst, uriAfterLast); \ + URI_EXPECT_OUTSIDE(range.afterLast, uriFirst, uriAfterLast) + +#define URI_EXPECT_RANGE_EMPTY(range) \ + EXPECT_TRUE((range.first != NULL) \ + && (range.afterLast != NULL) \ + && (range.first == range.afterLast)) + +namespace { + bool testDistinctionHelper(const char * uriText, bool expectedHostSet, + bool expectedAbsPath, bool expectedEmptyTailSegment) { + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + + int res = uriParseUriA(&state, uriText); + if (res != URI_SUCCESS) { + uriFreeUriMembersA(&uri); + return false; + } + + if (expectedHostSet != (uri.hostText.first != NULL)) { + uriFreeUriMembersA(&uri); + return false; + } + + if (expectedAbsPath != (uri.absolutePath == URI_TRUE)) { + uriFreeUriMembersA(&uri); + return false; + } + + if (expectedEmptyTailSegment != ((uri.pathTail != NULL) + && (uri.pathTail->text.first == uri.pathTail->text.afterLast))) { + uriFreeUriMembersA(&uri); + return false; + } + + uriFreeUriMembersA(&uri); + return true; + } +} // namespace + + +TEST(UriSuite, TestDistinction) { + /* +============================================================================ +Rule | Example | hostSet | absPath | emptySeg +------------------------------------|---------|---------|---------|--------- +1) URI = scheme ":" hier-part ... | | | | + 1) "//" authority path-abempty | "s://" | true | false | false + | "s:///" | true | false | true + | "s://a" | true | false | false + | "s://a/"| true | false | true + 2) path-absolute | "s:/" | false | true | false + 3) path-rootless | "s:a" | false | false | false + | "s:a/" | false | false | true + 4) path-empty | "s:" | false | false | false +------------------------------------|---------|---------|---------|--------- +2) relative-ref = relative-part ... | | | | + 1) "//" authority path-abempty | "//" | true | false | false + | "///" | true | false | true + 2) path-absolute | "/" | false | true | false + 3) path-noscheme | "a" | false | false | false + | "a/" | false | false | true + 4) path-empty | "" | false | false | false +============================================================================ + */ + ASSERT_TRUE(testDistinctionHelper("s://", true, false, false)); + ASSERT_TRUE(testDistinctionHelper("s:///", true, false, true)); + ASSERT_TRUE(testDistinctionHelper("s://a", true, false, false)); + ASSERT_TRUE(testDistinctionHelper("s://a/", true, false, true)); + ASSERT_TRUE(testDistinctionHelper("s:/", false, true, false)); + ASSERT_TRUE(testDistinctionHelper("s:a", false, false, false)); + ASSERT_TRUE(testDistinctionHelper("s:a/", false, false, true)); + ASSERT_TRUE(testDistinctionHelper("s:", false, false, false)); + + ASSERT_TRUE(testDistinctionHelper("//", true, false, false)); + ASSERT_TRUE(testDistinctionHelper("///", true, false, true)); + ASSERT_TRUE(testDistinctionHelper("/", false, true, false)); + ASSERT_TRUE(testDistinctionHelper("a", false, false, false)); + ASSERT_TRUE(testDistinctionHelper("a/", false, false, true)); + ASSERT_TRUE(testDistinctionHelper("", false, false, false)); +} + +TEST(UriSuite, TestIpFour) { + URI_TEST_IP_FOUR_FAIL("01.0.0.0"); + URI_TEST_IP_FOUR_FAIL("001.0.0.0"); + URI_TEST_IP_FOUR_FAIL("00.0.0.0"); + URI_TEST_IP_FOUR_FAIL("000.0.0.0"); + URI_TEST_IP_FOUR_FAIL("256.0.0.0"); + URI_TEST_IP_FOUR_FAIL("300.0.0.0"); + URI_TEST_IP_FOUR_FAIL("1111.0.0.0"); + URI_TEST_IP_FOUR_FAIL("-1.0.0.0"); + URI_TEST_IP_FOUR_FAIL("0.0.0"); + URI_TEST_IP_FOUR_FAIL("0.0.0."); + URI_TEST_IP_FOUR_FAIL("0.0.0.0."); + URI_TEST_IP_FOUR_FAIL("0.0.0.0.0"); + URI_TEST_IP_FOUR_FAIL("0.0..0"); + URI_TEST_IP_FOUR_FAIL(".0.0.0"); + + URI_TEST_IP_FOUR_PASS("255.0.0.0"); + URI_TEST_IP_FOUR_PASS("0.0.0.0"); + URI_TEST_IP_FOUR_PASS("1.0.0.0"); + URI_TEST_IP_FOUR_PASS("2.0.0.0"); + URI_TEST_IP_FOUR_PASS("3.0.0.0"); + URI_TEST_IP_FOUR_PASS("30.0.0.0"); +} + +TEST(UriSuite, TestIpSixPass) { + // Quad length + URI_TEST_IP_SIX_PASS("abcd::"); + + URI_TEST_IP_SIX_PASS("abcd::1"); + URI_TEST_IP_SIX_PASS("abcd::12"); + URI_TEST_IP_SIX_PASS("abcd::123"); + URI_TEST_IP_SIX_PASS("abcd::1234"); + + // Full length + URI_TEST_IP_SIX_PASS("2001:0db8:0100:f101:0210:a4ff:fee3:9566"); // lower hex + URI_TEST_IP_SIX_PASS("2001:0DB8:0100:F101:0210:A4FF:FEE3:9566"); // Upper hex + URI_TEST_IP_SIX_PASS("2001:db8:100:f101:210:a4ff:fee3:9566"); + URI_TEST_IP_SIX_PASS("2001:0db8:100:f101:0:0:0:1"); + URI_TEST_IP_SIX_PASS("1:2:3:4:5:6:255.255.255.255"); + + // Legal IPv4 + URI_TEST_IP_SIX_PASS("::1.2.3.4"); + URI_TEST_IP_SIX_PASS("3:4::5:1.2.3.4"); + URI_TEST_IP_SIX_PASS("::ffff:1.2.3.4"); + URI_TEST_IP_SIX_PASS("::0.0.0.0"); // Min IPv4 + URI_TEST_IP_SIX_PASS("::255.255.255.255"); // Max IPv4 + + // Zipper position + URI_TEST_IP_SIX_PASS("::1:2:3:4:5:6:7"); + URI_TEST_IP_SIX_PASS("1::1:2:3:4:5:6"); + URI_TEST_IP_SIX_PASS("1:2::1:2:3:4:5"); + URI_TEST_IP_SIX_PASS("1:2:3::1:2:3:4"); + URI_TEST_IP_SIX_PASS("1:2:3:4::1:2:3"); + URI_TEST_IP_SIX_PASS("1:2:3:4:5::1:2"); + URI_TEST_IP_SIX_PASS("1:2:3:4:5:6::1"); + URI_TEST_IP_SIX_PASS("1:2:3:4:5:6:7::"); + + // Zipper length + URI_TEST_IP_SIX_PASS("1:1:1::1:1:1:1"); + URI_TEST_IP_SIX_PASS("1:1:1::1:1:1"); + URI_TEST_IP_SIX_PASS("1:1:1::1:1"); + URI_TEST_IP_SIX_PASS("1:1::1:1"); + URI_TEST_IP_SIX_PASS("1:1::1"); + URI_TEST_IP_SIX_PASS("1::1"); + URI_TEST_IP_SIX_PASS("::1"); // == localhost + URI_TEST_IP_SIX_PASS("::"); // == all addresses + + // A few more variations + URI_TEST_IP_SIX_PASS("21ff:abcd::1"); + URI_TEST_IP_SIX_PASS("2001:db8:100:f101::1"); + URI_TEST_IP_SIX_PASS("a:b:c::12:1"); + URI_TEST_IP_SIX_PASS("a:b::0:1:2:3"); +} + +TEST(UriSuite, TestIpSixFail) { + // 5 char quad + URI_TEST_IP_SIX_FAIL("::12345"); + + // Two zippers + URI_TEST_IP_SIX_FAIL("abcd::abcd::abcd"); + + // Triple-colon zipper + URI_TEST_IP_SIX_FAIL(":::1234"); + URI_TEST_IP_SIX_FAIL("1234:::1234:1234"); + URI_TEST_IP_SIX_FAIL("1234:1234:::1234"); + URI_TEST_IP_SIX_FAIL("1234:::"); + + // No quads, just IPv4 + URI_TEST_IP_SIX_FAIL("1.2.3.4"); + URI_TEST_IP_SIX_FAIL("0001.0002.0003.0004"); + + // Five quads + URI_TEST_IP_SIX_FAIL("0000:0000:0000:0000:0000:1.2.3.4"); + + // Seven quads + URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0"); + URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:"); + URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:1.2.3.4"); + + // Nine quads (or more) + URI_TEST_IP_SIX_FAIL("1:2:3:4:5:6:7:8:9"); + URI_TEST_IP_SIX_FAIL("::2:3:4:5:6:7:8:9"); + URI_TEST_IP_SIX_FAIL("1:2:3:4::6:7:8:9"); + URI_TEST_IP_SIX_FAIL("1:2:3:4:5:6:7:8::"); + + // Invalid IPv4 part + URI_TEST_IP_SIX_FAIL("::ffff:001.02.03.004"); // Leading zeros + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.1111"); // Four char octet + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.256"); // > 255 + URI_TEST_IP_SIX_FAIL("::ffff:311.2.3.4"); // > 155 + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3:4"); // Not a dot + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3"); // Missing octet + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3."); // Missing octet + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3a.4"); // Hex in octet + URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.4:123"); // Crap input + + // Nonhex + URI_TEST_IP_SIX_FAIL("g:0:0:0:0:0:0"); +} + +TEST(UriSuite, TestIpSixOverread) { + UriUriA uri; + const char * errorPos; + + // NOTE: This string is designed to not have a terminator + char uriText[2 + 3 + 2 + 1 + 1]; + memcpy(uriText, "//[::44.1", sizeof(uriText)); + + EXPECT_EQ(uriParseSingleUriExA(&uri, uriText, + uriText + sizeof(uriText), &errorPos), URI_ERROR_SYNTAX); + EXPECT_EQ(errorPos, uriText + sizeof(uriText)); +} + +TEST(UriSuite, TestUri) { + UriParserStateA stateA; + UriParserStateW stateW; + UriUriA uriA; + UriUriW uriW; + + stateA.uri = &uriA; + stateW.uri = &uriW; + + // On/off for each + ASSERT_TRUE(0 == uriParseUriA(&stateA, "//user:pass@[::1]:80/segment/index.html?query#frag")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://[::1]:80/segment/index.html?query#frag")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]/segment/index.html?query#frag")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80?query#frag")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80/segment/index.html#frag")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80/segment/index.html?query")); + uriFreeUriMembersA(&uriA); + + // Schema, port, one segment + ASSERT_TRUE(0 == uriParseUriA(&stateA, "ftp://host:21/gnu/")); + uriFreeUriMembersA(&uriA); + + // Relative + ASSERT_TRUE(0 == uriParseUriA(&stateA, "one/two/three")); + ASSERT_TRUE(!uriA.absolutePath); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "/one/two/three")); + ASSERT_TRUE(uriA.absolutePath); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "//user:pass@localhost/one/two/three")); + uriFreeUriMembersA(&uriA); + + // Both narrow and wide string version + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://www.example.com/")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriW(&stateW, L"http://www.example.com/")); + uriFreeUriMembersW(&uriW); + + // Real life examples + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://sourceforge.net/projects/uriparser/")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://sourceforge.net/project/platformdownload.php?group_id=182840")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "mailto:test@example.com")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "../../")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "/")); + ASSERT_TRUE(uriA.absolutePath); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "")); + ASSERT_TRUE(!uriA.absolutePath); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 == uriParseUriA(&stateA, "file:///bin/bash")); + uriFreeUriMembersA(&uriA); + + // Percent encoding + ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://www.example.com/name%20with%20spaces/")); + uriFreeUriMembersA(&uriA); + ASSERT_TRUE(0 != uriParseUriA(&stateA, "http://www.example.com/name with spaces/")); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriComponents) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 15 01 0 7 01 + const char * const input = "http" "://" "sourceforge.net" "/" "project" "/" + // 0 20 01 0 15 + "platformdownload.php" "?" "group_id=182840"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.scheme.first == input); + ASSERT_TRUE(uriA.scheme.afterLast == input + 4); + ASSERT_TRUE(uriA.userInfo.first == NULL); + ASSERT_TRUE(uriA.userInfo.afterLast == NULL); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 15); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + + ASSERT_TRUE(uriA.pathHead->text.first == input + 4 + 3 + 15 + 1); + ASSERT_TRUE(uriA.pathHead->text.afterLast == input + 4 + 3 + 15 + 1 + 7); + ASSERT_TRUE(uriA.pathHead->next->text.first == input + 4 + 3 + 15 + 1 + 7 + 1); + ASSERT_TRUE(uriA.pathHead->next->text.afterLast == input + 4 + 3 + 15 + 1 + 7 + 1 + 20); + ASSERT_TRUE(uriA.pathHead->next->next == NULL); + ASSERT_TRUE(uriA.pathTail == uriA.pathHead->next); + + ASSERT_TRUE(uriA.query.first == input + 4 + 3 + 15 + 1 + 7 + 1 + 20 + 1); + ASSERT_TRUE(uriA.query.afterLast == input + 4 + 3 + 15 + 1 + 7 + 1 + 20 + 1 + 15); + ASSERT_TRUE(uriA.fragment.first == NULL); + ASSERT_TRUE(uriA.fragment.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriComponentsBug20070701) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 01 01 01 + const char * const input = "a" ":" "b"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.scheme.first == input); + ASSERT_TRUE(uriA.scheme.afterLast == input + 1); + ASSERT_TRUE(uriA.userInfo.first == NULL); + ASSERT_TRUE(uriA.userInfo.afterLast == NULL); + ASSERT_TRUE(uriA.hostText.first == NULL); + ASSERT_TRUE(uriA.hostText.afterLast == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + + ASSERT_TRUE(uriA.pathHead->text.first == input + 1 + 1); + ASSERT_TRUE(uriA.pathHead->text.afterLast == input + 1 + 1 + 1); + ASSERT_TRUE(uriA.pathHead->next == NULL); + ASSERT_TRUE(uriA.pathTail == uriA.pathHead); + + ASSERT_TRUE(uriA.query.first == NULL); + ASSERT_TRUE(uriA.query.afterLast == NULL); + ASSERT_TRUE(uriA.fragment.first == NULL); + ASSERT_TRUE(uriA.fragment.afterLast == NULL); + + ASSERT_TRUE(!uriA.absolutePath); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort1) { + // User info with ":", no port + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 7 01 0 9 + const char * const input = "http" "://" "abc:def" "@" "localhost"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3); + ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort2) { + // User info with ":", with port + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 7 01 0 9 + const char * const input = "http" "://" "abc:def" "@" "localhost" + // 01 0 3 + ":" "123"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3); + ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9); + ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 7 + 1 + 9 + 1); + ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 7 + 1 + 9 + 1 + 3); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort22Bug1948038) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + + res = uriParseUriA(&stateA, "http://user:21@host/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(!memcmp(uriA.userInfo.first, "user:21", 7 * sizeof(char))); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 7); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); + + res = uriParseUriA(&stateA, "http://user:1234@192.168.0.1:1234/foo.com"); + ASSERT_TRUE(URI_SUCCESS == res); + uriFreeUriMembersA(&uriA); + + res = uriParseUriA(&stateA, "http://moo:21@moo:21@moo/"); + ASSERT_TRUE(URI_ERROR_SYNTAX == res); + uriFreeUriMembersA(&uriA); + + res = uriParseUriA(&stateA, "http://moo:21@moo:21@moo:21/"); + ASSERT_TRUE(URI_ERROR_SYNTAX == res); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198One) { + // User info with ":", with port, with escaped chars in password + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 0 10 01 0 4 01 + res = uriParseUriA(&stateA, "http" "://" "user:%2F21" "@" "host" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(!memcmp(uriA.userInfo.first, "user:%2F21", 10 * sizeof(char))); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 10); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198Two) { + // User info with ":", with port, with escaped chars in user name and password + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 0 13 01 0 4 01 + res = uriParseUriA(&stateA, "http" "://" "%2Fuser:%2F21" "@" "host" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(!memcmp(uriA.userInfo.first, "%2Fuser:%2F21", 13 * sizeof(char))); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 13); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198Three) { + // User info with ":", with port, with escaped chars in password + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 0 16 01 0 4 01 + res = uriParseUriA(&stateA, "http" "://" "user:!$&'()*+,;=" "@" "host" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(!memcmp(uriA.userInfo.first, "user:!$&'()*+,;=", 16 * sizeof(char))); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 16); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198Four) { + // User info with ":", with port, with escaped chars in user name and password + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 0 20 01 0 4 01 + res = uriParseUriA(&stateA, "http" "://" "!$&'()*+,;=:password" "@" "host" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(!memcmp(uriA.userInfo.first, "!$&'()*+,;=:password", 20 * sizeof(char))); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 20); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198RelatedOne) { + // Empty user info + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 01 0 4 01 + res = uriParseUriA(&stateA, "http" "://" "@" "host" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(uriA.userInfo.afterLast != NULL); + ASSERT_TRUE(uriA.userInfo.first != NULL); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 0); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198RelatedOneTwo) { + // Empty user info + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 0 7 01 + res = uriParseUriA(&stateA, "http" "://" "%2Fhost" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(uriA.userInfo.afterLast == NULL); + ASSERT_TRUE(uriA.userInfo.first == NULL); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "%2Fhost", 7 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 7); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198RelatedTwo) { + // Several colons in userinfo + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + + int res; + // 0 4 0 3 0 2 01 0 4 01 + res = uriParseUriA(&stateA, "http" "://" "::" "@" "host" "/"); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(!memcmp(uriA.userInfo.first, "::", 2 * sizeof(char))); + ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 2); + ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char))); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort3) { + // User info without ":", no port + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 7 01 0 9 + const char * const input = "http" "://" "abcdefg" "@" "localhost"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3); + ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort4) { + // User info without ":", with port + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 7 01 0 9 + const char * const input = "http" "://" "abcdefg" "@" "localhost" + // 01 0 3 + ":" "123"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3); + ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9); + ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 7 + 1 + 9 + 1); + ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 7 + 1 + 9 + 1 + 3); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort5) { + // No user info, no port + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 9 + const char * const input = "http" "://" "localhost"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.userInfo.first == NULL); + ASSERT_TRUE(uriA.userInfo.afterLast == NULL); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 9); + ASSERT_TRUE(uriA.portText.first == NULL); + ASSERT_TRUE(uriA.portText.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriUserInfoHostPort6) { + // No user info, with port + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 9 01 0 3 + const char * const input = "http" "://" "localhost" ":" "123"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.userInfo.first == NULL); + ASSERT_TRUE(uriA.userInfo.afterLast == NULL); + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 9); + ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 9 + 1); + ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 9 + 1 + 3); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostRegname) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 11 + const char * const input = "http" "://" "example.com"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 11); + ASSERT_TRUE(uriA.hostData.ip4 == NULL); + ASSERT_TRUE(uriA.hostData.ip6 == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostIpFour1) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 7 01 0 2 + const char * const input = "http" "://" "1.2.3.4" ":" "80"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7); + ASSERT_TRUE(uriA.hostData.ip4 != NULL); + ASSERT_TRUE(uriA.hostData.ip6 == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostIpFour2) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 0 7 + const char * const input = "http" "://" "1.2.3.4"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7); + ASSERT_TRUE(uriA.hostData.ip4 != NULL); + ASSERT_TRUE(uriA.hostData.ip6 == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostIpSix1) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 01 45 01 0 2 + const char * const input = "http" "://" "[::1]" ":" "80"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 1); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 4); + ASSERT_TRUE(uriA.hostData.ip4 == NULL); + ASSERT_TRUE(uriA.hostData.ip6 != NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostIpSix2) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 01 45 + const char * const input = "http" "://" "[::1]"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 1); + ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 4); + ASSERT_TRUE(uriA.hostData.ip4 == NULL); + ASSERT_TRUE(uriA.hostData.ip6 != NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL); + ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostEmpty) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 4 0 3 01 0 3 + const char * const input = "http" "://" ":" "123"; + const int res = uriParseUriA(&stateA, input); + ASSERT_TRUE(URI_SUCCESS == res); + ASSERT_TRUE(uriA.userInfo.first == NULL); + ASSERT_TRUE(uriA.userInfo.afterLast == NULL); + ASSERT_TRUE(uriA.hostText.first != NULL); + ASSERT_TRUE(uriA.hostText.afterLast != NULL); + ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 0); + ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 1); + ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 1 + 3); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestUriHostIpFuture) { + // TODO +} + +namespace { + bool testEscapingHelper(const wchar_t * in, const wchar_t * expectedOut, + bool spaceToPlus = false, bool normalizeBreaks = false) { + wchar_t * const buffer = new wchar_t[(normalizeBreaks ? 6 : 3) + * wcslen(in) + 1]; + if (uriEscapeW(in, buffer, spaceToPlus, normalizeBreaks) + != buffer + wcslen(expectedOut)) { + delete [] buffer; + return false; + } + + const bool equal = !wcscmp(buffer, expectedOut); + delete [] buffer; + return equal; + } +} // namespace + +TEST(UriSuite, TestEscaping) { + const bool SPACE_TO_PLUS = true; + const bool SPACE_TO_PERCENT = false; + const bool KEEP_UNMODIFIED = false; + const bool NORMALIZE = true; + + // '+' to ' ' + ASSERT_TRUE(testEscapingHelper(L"abc def", L"abc+def", SPACE_TO_PLUS)); + ASSERT_TRUE(testEscapingHelper(L"abc def", L"abc%20def", SPACE_TO_PERCENT)); + + // Percent encoding + ASSERT_TRUE(testEscapingHelper(L"\x00", L"\0")); + ASSERT_TRUE(testEscapingHelper(L"\x01", L"%01")); + ASSERT_TRUE(testEscapingHelper(L"\xff", L"%FF")); + + // Linebreak normalization + ASSERT_TRUE(testEscapingHelper(L"\x0d", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"g\x0d", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0dg", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0d", L"%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"g\x0d", L"g%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"\x0dg", L"%0Dg", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + + ASSERT_TRUE(testEscapingHelper(L"\x0a", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"g\x0a", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0a", L"%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"g\x0a", L"g%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"\x0ag", L"%0Ag", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + + ASSERT_TRUE(testEscapingHelper(L"\x0d\x0a", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"g\x0d\x0a", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0d\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0d\x0a", L"%0D%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"g\x0d\x0a", L"g%0D%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"\x0d\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + + ASSERT_TRUE(testEscapingHelper(L"\x0a\x0d", L"%0D%0A%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"g\x0a\x0d", L"g%0D%0A%0D%0A", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0a\x0dg", L"%0D%0A%0D%0Ag", SPACE_TO_PLUS, NORMALIZE)); + ASSERT_TRUE(testEscapingHelper(L"\x0a\x0d", L"%0A%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"g\x0a\x0d", L"g%0A%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED)); + ASSERT_TRUE(testEscapingHelper(L"\x0a\x0dg", L"%0A%0Dg", SPACE_TO_PLUS, KEEP_UNMODIFIED)); +} + +namespace { + bool testUnescapingHelper(const wchar_t * input, const wchar_t * output, + bool plusToSpace = false, UriBreakConversion breakConversion = URI_BR_DONT_TOUCH) { + wchar_t * working = new wchar_t[URI_STRLEN(input) + 1]; + wcscpy(working, input); + const wchar_t * newTermZero = uriUnescapeInPlaceExW(working, + plusToSpace ? URI_TRUE : URI_FALSE, breakConversion); + const bool success = ((newTermZero == working + wcslen(output)) + && !wcscmp(working, output)); + delete[] working; + return success; + } +} // namespace + +TEST(UriSuite, TestUnescaping) { + const bool PLUS_TO_SPACE = true; + const bool PLUS_DONT_TOUCH = false; + + + // Proper + ASSERT_TRUE(testUnescapingHelper(L"abc%20%41BC", L"abc ABC")); + ASSERT_TRUE(testUnescapingHelper(L"%20", L" ")); + + // Incomplete + ASSERT_TRUE(testUnescapingHelper(L"%0", L"%0")); + + // Nonhex + ASSERT_TRUE(testUnescapingHelper(L"%0g", L"%0g")); + ASSERT_TRUE(testUnescapingHelper(L"%G0", L"%G0")); + + // No double decoding + ASSERT_TRUE(testUnescapingHelper(L"%2520", L"%20")); + + // Decoding of '+' + ASSERT_TRUE(testUnescapingHelper(L"abc+def", L"abc+def", PLUS_DONT_TOUCH)); + ASSERT_TRUE(testUnescapingHelper(L"abc+def", L"abc def", PLUS_TO_SPACE)); + + // Line break conversion + ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + + ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0a\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0d\x0a\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0d\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0a\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); + + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0a\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0d\x0a\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0d\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC)); + ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0a\x0d\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH)); +} + +namespace { + bool testAddBaseHelper(const wchar_t * base, const wchar_t * rel, const wchar_t * expectedResult, bool backward_compatibility = false) { + UriParserStateW stateW; + + // Base + UriUriW baseUri; + stateW.uri = &baseUri; + int res = uriParseUriW(&stateW, base); + if (res != 0) { + uriFreeUriMembersW(&baseUri); + return false; + } + + // Rel + UriUriW relUri; + stateW.uri = &relUri; + res = uriParseUriW(&stateW, rel); + if (res != 0) { + uriFreeUriMembersW(&baseUri); + uriFreeUriMembersW(&relUri); + return false; + } + + // Expected result + UriUriW expectedUri; + stateW.uri = &expectedUri; + res = uriParseUriW(&stateW, expectedResult); + if (res != 0) { + uriFreeUriMembersW(&baseUri); + uriFreeUriMembersW(&relUri); + uriFreeUriMembersW(&expectedUri); + return false; + } + + // Transform + UriUriW transformedUri; + if (backward_compatibility) { + res = uriAddBaseUriExW(&transformedUri, &relUri, &baseUri, URI_RESOLVE_IDENTICAL_SCHEME_COMPAT); + } else { + res = uriAddBaseUriW(&transformedUri, &relUri, &baseUri); + } + + if (res != 0) { + uriFreeUriMembersW(&baseUri); + uriFreeUriMembersW(&relUri); + uriFreeUriMembersW(&expectedUri); + uriFreeUriMembersW(&transformedUri); + return false; + } + + const bool equal = (URI_TRUE == uriEqualsUriW(&transformedUri, &expectedUri)); + if (!equal) { + wchar_t transformedUriText[1024 * 8]; + wchar_t expectedUriText[1024 * 8]; + uriToStringW(transformedUriText, &transformedUri, 1024 * 8, NULL); + uriToStringW(expectedUriText, &expectedUri, 1024 * 8, NULL); +#ifdef HAVE_WPRINTF + wprintf(L"\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", expectedUriText, transformedUriText); +#endif + } + + uriFreeUriMembersW(&baseUri); + uriFreeUriMembersW(&relUri); + uriFreeUriMembersW(&expectedUri); + uriFreeUriMembersW(&transformedUri); + return equal; + } +} // namespace + +TEST(UriSuite, TestTrailingSlash) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + // 0 3 01 + const char * const input = "abc" "/"; + ASSERT_TRUE(0 == uriParseUriA(&stateA, input)); + + ASSERT_TRUE(uriA.pathHead->text.first == input); + ASSERT_TRUE(uriA.pathHead->text.afterLast == input + 3); + ASSERT_TRUE(uriA.pathHead->next->text.first == uriA.pathHead->next->text.afterLast); + ASSERT_TRUE(uriA.pathHead->next->next == NULL); + ASSERT_TRUE(uriA.pathTail == uriA.pathHead->next); + uriFreeUriMembersA(&uriA); +} + +TEST(UriSuite, TestAddBase) { + // 5.4.1. Normal Examples + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g:h", L"g:h")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g", L"http://a/b/c/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./g", L"http://a/b/c/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/", L"http://a/b/c/g/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g", L"http://a/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"//g", L"http://g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"?y", L"http://a/b/c/d;p?y")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y", L"http://a/b/c/g?y")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"#s", L"http://a/b/c/d;p?q#s")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s", L"http://a/b/c/g#s")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y#s", L"http://a/b/c/g?y#s")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L";x", L"http://a/b/c/;x")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x", L"http://a/b/c/g;x")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x?y#s", L"http://a/b/c/g;x?y#s")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"", L"http://a/b/c/d;p?q")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L".", L"http://a/b/c/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./", L"http://a/b/c/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"..", L"http://a/b/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../", L"http://a/b/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../g", L"http://a/b/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../..", L"http://a/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../", L"http://a/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../g", L"http://a/g")); + + // 5.4.2. Abnormal Examples + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../g", L"http://a/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../../g", L"http://a/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/./g", L"http://a/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/../g", L"http://a/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g.", L"http://a/b/c/g.")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L".g", L"http://a/b/c/.g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g..", L"http://a/b/c/g..")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"..g", L"http://a/b/c/..g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./../g", L"http://a/b/g")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./g/.", L"http://a/b/c/g/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/./h", L"http://a/b/c/g/h")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/../h", L"http://a/b/c/h")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x=1/./y", L"http://a/b/c/g;x=1/y")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x=1/../y", L"http://a/b/c/y")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y/./x", L"http://a/b/c/g?y/./x")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y/../x", L"http://a/b/c/g?y/../x")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s/./x", L"http://a/b/c/g#s/./x")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s/../x", L"http://a/b/c/g#s/../x")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http:g")); + + // Backward compatibility (feature request #4, RFC3986 5.4.2) + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http:g", false)); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http://a/b/c/g", true)); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g?q#f", L"http://a/b/c/g?q#f", true)); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"other:g?q#f", L"other:g?q#f", true)); + + // Bug related to absolutePath flag set despite presence of host + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/", L"http://a/")); + ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g/", L"http://a/g/")); + + // GitHub issue #92 + EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../..", L"http://a/")); + EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../../", L"http://a/")); + + EXPECT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../..", L"http://a/")); + EXPECT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../../", L"http://a/")); + + EXPECT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../..", L"http://a/")); + EXPECT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../../", L"http://a/")); + + EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../..", L"http://a/")); + EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../", L"http://a/")); +} + +namespace { + bool testToStringHelper(const wchar_t * text) { + // Parse + UriParserStateW state; + UriUriW uri; + state.uri = &uri; + int res = uriParseUriW(&state, text); + if (res != 0) { + uriFreeUriMembersW(&uri); + return false; + } + + // Back to string, _huge_ limit + wchar_t shouldbeTheSame[1024 * 8]; + res = uriToStringW(shouldbeTheSame, &uri, 1024 * 8, NULL); + if (res != 0) { + uriFreeUriMembersW(&uri); + return false; + } + + // Compare + bool equals = (0 == wcscmp(shouldbeTheSame, text)); + if (!equals) { +#ifdef HAVE_WPRINTF + wprintf(L"\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", text, shouldbeTheSame); +#endif + } + + // Back to string, _exact_ limit + const int len = static_cast<int>(wcslen(text)); + int charsWritten; + res = uriToStringW(shouldbeTheSame, &uri, len + 1, &charsWritten); + if ((res != 0) || (charsWritten != len + 1)) { + uriFreeUriMembersW(&uri); + return false; + } + + // Back to string, _too small_ limit + res = uriToStringW(shouldbeTheSame, &uri, len, &charsWritten); + if ((res == 0) || (charsWritten >= len + 1)) { + uriFreeUriMembersW(&uri); + return false; + } + + uriFreeUriMembersW(&uri); + return equals; + } +} // namespace + +TEST(UriSuite, TestToString) { + // Scheme + ASSERT_TRUE(testToStringHelper(L"ftp://localhost/")); + // UserInfo + ASSERT_TRUE(testToStringHelper(L"http://user:pass@localhost/")); + // IPv4 + ASSERT_TRUE(testToStringHelper(L"http://123.0.1.255/")); + // IPv6 + ASSERT_TRUE(testToStringHelper(L"http://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]/")); + // IPvFuture + ASSERT_TRUE(testToStringHelper(L"http://[vA.123456]/")); + // Port + ASSERT_TRUE(testToStringHelper(L"http://example.com:123/")); + // Path + ASSERT_TRUE(testToStringHelper(L"http://example.com")); + ASSERT_TRUE(testToStringHelper(L"http://example.com/")); + ASSERT_TRUE(testToStringHelper(L"http://example.com/abc/")); + ASSERT_TRUE(testToStringHelper(L"http://example.com/abc/def")); + ASSERT_TRUE(testToStringHelper(L"http://example.com/abc/def/")); + ASSERT_TRUE(testToStringHelper(L"http://example.com//")); + ASSERT_TRUE(testToStringHelper(L"http://example.com/./..")); + // Query + ASSERT_TRUE(testToStringHelper(L"http://example.com/?abc")); + // Fragment + ASSERT_TRUE(testToStringHelper(L"http://example.com/#abc")); + ASSERT_TRUE(testToStringHelper(L"http://example.com/?def#abc")); + + // Relative + ASSERT_TRUE(testToStringHelper(L"a")); + ASSERT_TRUE(testToStringHelper(L"a/")); + ASSERT_TRUE(testToStringHelper(L"/a")); + ASSERT_TRUE(testToStringHelper(L"/a/")); + ASSERT_TRUE(testToStringHelper(L"abc")); + ASSERT_TRUE(testToStringHelper(L"abc/")); + ASSERT_TRUE(testToStringHelper(L"/abc")); + ASSERT_TRUE(testToStringHelper(L"/abc/")); + ASSERT_TRUE(testToStringHelper(L"a/def")); + ASSERT_TRUE(testToStringHelper(L"a/def/")); + ASSERT_TRUE(testToStringHelper(L"/a/def")); + ASSERT_TRUE(testToStringHelper(L"/a/def/")); + ASSERT_TRUE(testToStringHelper(L"abc/def")); + ASSERT_TRUE(testToStringHelper(L"abc/def/")); + ASSERT_TRUE(testToStringHelper(L"/abc/def")); + ASSERT_TRUE(testToStringHelper(L"/abc/def/")); + ASSERT_TRUE(testToStringHelper(L"/")); + ASSERT_TRUE(testToStringHelper(L"//a/")); + ASSERT_TRUE(testToStringHelper(L".")); + ASSERT_TRUE(testToStringHelper(L"./")); + ASSERT_TRUE(testToStringHelper(L"/.")); + ASSERT_TRUE(testToStringHelper(L"/./")); + ASSERT_TRUE(testToStringHelper(L"")); + ASSERT_TRUE(testToStringHelper(L"./abc/def")); + ASSERT_TRUE(testToStringHelper(L"?query")); + ASSERT_TRUE(testToStringHelper(L"#fragment")); + ASSERT_TRUE(testToStringHelper(L"?query#fragment")); + + // Tests for bugs from the past + ASSERT_TRUE(testToStringHelper(L"f:/.//g")); +} + +TEST(UriSuite, TestToStringBug1950126) { + UriParserStateW state; + UriUriW uriOne; + UriUriW uriTwo; + const wchar_t * const uriOneString = L"http://e.com/"; + const wchar_t * const uriTwoString = L"http://e.com"; + state.uri = &uriOne; + ASSERT_TRUE(URI_SUCCESS == uriParseUriW(&state, uriOneString)); + state.uri = &uriTwo; + ASSERT_TRUE(URI_SUCCESS == uriParseUriW(&state, uriTwoString)); + ASSERT_TRUE(URI_FALSE == uriEqualsUriW(&uriOne, &uriTwo)); + uriFreeUriMembersW(&uriOne); + uriFreeUriMembersW(&uriTwo); + + ASSERT_TRUE(testToStringHelper(uriOneString)); + ASSERT_TRUE(testToStringHelper(uriTwoString)); +} + +namespace { + bool testToStringCharsRequiredHelper(const wchar_t * text) { + // Parse + UriParserStateW state; + UriUriW uri; + state.uri = &uri; + int res = uriParseUriW(&state, text); + if (res != 0) { + uriFreeUriMembersW(&uri); + return false; + } + + // Required space? + int charsRequired; + if (uriToStringCharsRequiredW(&uri, &charsRequired) != 0) { + uriFreeUriMembersW(&uri); + return false; + } + + EXPECT_EQ(charsRequired, wcslen(text)); + + // Minimum + wchar_t * buffer = new wchar_t[charsRequired + 1]; + if (uriToStringW(buffer, &uri, charsRequired + 1, NULL) != 0) { + uriFreeUriMembersW(&uri); + delete [] buffer; + return false; + } + + // One less than minimum + if (uriToStringW(buffer, &uri, charsRequired, NULL) == 0) { + uriFreeUriMembersW(&uri); + delete [] buffer; + return false; + } + + uriFreeUriMembersW(&uri); + delete [] buffer; + return true; + } +} // namespace + +TEST(UriSuite, TestToStringCharsRequired) { + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.1.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://12.1.1.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://123.1.1.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.12.1.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.123.1.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.12.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.123.1/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.1.12/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.1.123/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com:80/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://user:pass@www.example.com/")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/index.html")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/?abc")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/#def")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/?abc#def")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"/test")); + EXPECT_TRUE(testToStringCharsRequiredHelper(L"test")); +} + +namespace { + bool testNormalizeMaskHelper(const wchar_t * uriText, unsigned int expectedMask) { + UriParserStateW state; + UriUriW uri; + state.uri = &uri; + int res = uriParseUriW(&state, uriText); + if (res != 0) { + uriFreeUriMembersW(&uri); + return false; + } + + const unsigned int maskBefore = uriNormalizeSyntaxMaskRequiredW(&uri); + if (maskBefore != expectedMask) { + uriFreeUriMembersW(&uri); + return false; + } + + res = uriNormalizeSyntaxW(&uri); + if (res != 0) { + uriFreeUriMembersW(&uri); + return false; + } + + const unsigned int maskAfter = uriNormalizeSyntaxMaskRequiredW(&uri); + uriFreeUriMembersW(&uri); + + // Second call should be no problem + uriFreeUriMembersW(&uri); + + return (maskAfter == URI_NORMALIZED); + } +} // namespace + +TEST(UriSuite, TestNormalizeSyntaxMaskRequired) { + ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/", URI_NORMALIZED)); + ASSERT_TRUE(testNormalizeMaskHelper(L"httP://localhost/", URI_NORMALIZE_SCHEME)); + ASSERT_TRUE(testNormalizeMaskHelper(L"http://%0d@localhost/", URI_NORMALIZE_USER_INFO)); + ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhosT/", URI_NORMALIZE_HOST)); + ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/./abc", URI_NORMALIZE_PATH)); + ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/?AB%43", URI_NORMALIZE_QUERY)); + ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/#AB%43", URI_NORMALIZE_FRAGMENT)); +} + +namespace { + bool testNormalizeSyntaxHelper(const wchar_t * uriText, const wchar_t * expectedNormalized, + unsigned int mask = static_cast<unsigned int>(-1)) { + UriParserStateW stateW; + int res; + + UriUriW testUri; + stateW.uri = &testUri; + res = uriParseUriW(&stateW, uriText); + if (res != 0) { + uriFreeUriMembersW(&testUri); + return false; + } + + // Expected result + UriUriW expectedUri; + stateW.uri = &expectedUri; + res = uriParseUriW(&stateW, expectedNormalized); + if (res != 0) { + uriFreeUriMembersW(&testUri); + uriFreeUriMembersW(&expectedUri); + return false; + } + + // First run + res = uriNormalizeSyntaxExW(&testUri, mask); + if (res != 0) { + uriFreeUriMembersW(&testUri); + uriFreeUriMembersW(&expectedUri); + return false; + } + + bool equalAfter = (URI_TRUE == uriEqualsUriW(&testUri, &expectedUri)); + + // Second run + res = uriNormalizeSyntaxExW(&testUri, mask); + if (res != 0) { + uriFreeUriMembersW(&testUri); + uriFreeUriMembersW(&expectedUri); + return false; + } + + equalAfter = equalAfter + && (URI_TRUE == uriEqualsUriW(&testUri, &expectedUri)); + + uriFreeUriMembersW(&testUri); + uriFreeUriMembersW(&expectedUri); + return equalAfter; + } +} // namespace + +TEST(UriSuite, TestNormalizeSyntax) { + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"eXAMPLE://a/./b/../b/%63/%7bfoo%7d", + L"example://a/b/c/%7Bfoo%7D")); + + // Testcase by Adrian Manrique + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"http://examp%4Ce.com/", + L"http://example.com/")); + + // Testcase by Adrian Manrique + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"http://example.com/a/b/%2E%2E/", + L"http://example.com/a/")); + + // Reported by Adrian Manrique + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"http://user:pass@SOMEHOST.COM:123", + L"http://user:pass@somehost.com:123")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://a:b@HOST:123/./1/2/../%41?abc#def", + L"http://a:b@host:123/1/A?abc#def")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"../../abc", + L"../../abc")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"../../abc/..", + L"../../")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"../../abc/../def", + L"../../def")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"abc/..", + L"")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"abc/../", + L"")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"../../abc/./def", + L"../../abc/def")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"./def", + L"def")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"def/.", + L"def/")); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"./abc:def", + L"./abc:def")); +} + +TEST(UriSuite, TestNormalizeSyntaxComponents) { + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41", + L"http://%41@EXAMPLE.ORG/../a?%41#%41", + URI_NORMALIZE_SCHEME)); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41", + L"HTTP://A@EXAMPLE.ORG/../a?%41#%41", + URI_NORMALIZE_USER_INFO)); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41", + L"HTTP://%41@example.org/../a?%41#%41", + URI_NORMALIZE_HOST)); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41", + L"HTTP://%41@EXAMPLE.ORG/a?%41#%41", + URI_NORMALIZE_PATH)); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41", + L"HTTP://%41@EXAMPLE.ORG/../a?A#%41", + URI_NORMALIZE_QUERY)); + + ASSERT_TRUE(testNormalizeSyntaxHelper( + L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41", + L"HTTP://%41@EXAMPLE.ORG/../a?%41#A", + URI_NORMALIZE_FRAGMENT)); +} + +TEST(UriSuite, TestNormalizeSyntaxPath) { + // These are from GitHub issue #92 + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"http://a/b/c/../../..", + L"http://a/", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"http://a/b/../c/../..", + L"http://a/", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"http://a/b/c/../../..", + L"http://a/", + URI_NORMALIZE_PATH)); + + // .. and these are related + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"http://a/..", + L"http://a/", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"/..", + L"/", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"http://a/..///", + L"http://a///", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"http://a/..///..", + L"http://a//", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"a/b/c/../../..", + L"", + URI_NORMALIZE_PATH)); + EXPECT_TRUE(testNormalizeSyntaxHelper( + L"a/b/../../c/..", + L"", + URI_NORMALIZE_PATH)); +} + +TEST(UriSuite, TestNormalizeCrashBug20080224) { + UriParserStateW stateW; + int res; + UriUriW testUri; + stateW.uri = &testUri; + + res = uriParseUriW(&stateW, L"http://example.org/abc//../def"); + ASSERT_TRUE(res == 0); + + // First call will make us owner of copied memory + res = uriNormalizeSyntaxExW(&testUri, URI_NORMALIZE_SCHEME); + ASSERT_TRUE(res == 0); + res = uriNormalizeSyntaxExW(&testUri, URI_NORMALIZE_HOST); + ASSERT_TRUE(res == 0); + + // Frees empty path segment -> crash + res = uriNormalizeSyntaxW(&testUri); + ASSERT_TRUE(res == 0); + + uriFreeUriMembersW(&testUri); +} + +namespace { + void testFilenameUriConversionHelper(const wchar_t * filename, + const wchar_t * uriString, bool forUnix, + const wchar_t * expectedUriString = NULL) { + const int prefixLen = forUnix ? 7 : 8; + if (! expectedUriString) { + expectedUriString = uriString; + } + + // Filename to URI string + const size_t uriBufferLen = prefixLen + 3 * wcslen(filename) + 1; + wchar_t * uriBuffer = new wchar_t[uriBufferLen]; + if (forUnix) { + uriUnixFilenameToUriStringW(filename, uriBuffer); + } else { + uriWindowsFilenameToUriStringW(filename, uriBuffer); + } +#ifdef HAVE_WPRINTF + // wprintf(L"1 [%s][%s]\n", uriBuffer, expectedUriString); +#endif + ASSERT_TRUE(!wcscmp(uriBuffer, expectedUriString)); + delete [] uriBuffer; + + // URI string to filename + const size_t filenameBufferLen = wcslen(uriString) + 1; + wchar_t * filenameBuffer = new wchar_t[filenameBufferLen]; + if (forUnix) { + uriUriStringToUnixFilenameW(uriString, filenameBuffer); + } else { + uriUriStringToWindowsFilenameW(uriString, filenameBuffer); + } +#ifdef HAVE_WPRINTF + // wprintf(L"2 [%s][%s]\n", filenameBuffer, filename); +#endif + ASSERT_TRUE(!wcscmp(filenameBuffer, filename)); + delete [] filenameBuffer; + } +} // namespace + +TEST(UriSuite, TestFilenameUriConversion) { + const bool FOR_UNIX = true; + const bool FOR_WINDOWS = false; + testFilenameUriConversionHelper(L"/bin/bash", L"file:///bin/bash", FOR_UNIX); + testFilenameUriConversionHelper(L"/bin/bash", L"file:/bin/bash", FOR_UNIX, L"file:///bin/bash"); + testFilenameUriConversionHelper(L"./configure", L"./configure", FOR_UNIX); + + testFilenameUriConversionHelper(L"E:\\Documents and Settings", L"file:///E:/Documents%20and%20Settings", FOR_WINDOWS); + testFilenameUriConversionHelper(L"c:\\path\\to\\file.txt", L"file:c:/path/to/file.txt", FOR_WINDOWS, L"file:///c:/path/to/file.txt"); + + testFilenameUriConversionHelper(L".\\Readme.txt", L"./Readme.txt", FOR_WINDOWS); + + testFilenameUriConversionHelper(L"index.htm", L"index.htm", FOR_WINDOWS); + testFilenameUriConversionHelper(L"index.htm", L"index.htm", FOR_UNIX); + + testFilenameUriConversionHelper(L"abc def", L"abc%20def", FOR_WINDOWS); + testFilenameUriConversionHelper(L"abc def", L"abc%20def", FOR_UNIX); + + testFilenameUriConversionHelper(L"\\\\Server01\\user\\docs\\Letter.txt", L"file://Server01/user/docs/Letter.txt", FOR_WINDOWS); +} + +TEST(UriSuite, TestCrashFreeUriMembersBug20080116) { + // Testcase by Adrian Manrique + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + uriParseUriA(&state, "http://test/?"); + uriNormalizeSyntaxA(&uri); + uriFreeUriMembersA(&uri); + + ASSERT_TRUE(true); +} + +namespace { + void helperTestQueryString(char const * uriString, int pairsExpected); +} + +TEST(UriSuite, TestCrashReport2418192) { + // Testcase by Harvey Vrsalovic + helperTestQueryString("http://svcs.cnn.com/weather/wrapper.jsp?&csiID=csi1", 1); +} + +TEST(UriSuite, TestPervertedQueryString) { + helperTestQueryString("http://example.org/?&&=&&&=&&&&==&===&====", 5); +} + +TEST(UriSuite, TestQueryStringEndingInEqualSignNonBug32) { + const char * queryString = "firstname=sdsd&lastname="; + + UriQueryListA * queryList = NULL; + int itemCount = 0; + const int res = uriDissectQueryMallocA(&queryList, &itemCount, + queryString, queryString + strlen(queryString)); + + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(itemCount == 2); + ASSERT_TRUE(queryList != NULL); + ASSERT_TRUE(strcmp(queryList->key, "firstname") == 0); + ASSERT_TRUE(strcmp(queryList->value, "sdsd") == 0); + ASSERT_TRUE(strcmp(queryList->next->key, "lastname") == 0); + ASSERT_TRUE(strcmp(queryList->next->value, "") == 0); + ASSERT_TRUE(queryList->next->next == NULL); + + uriFreeQueryListA(queryList); +} + +namespace { + void helperTestQueryString(char const * uriString, int pairsExpected) { + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + int res = uriParseUriA(&state, uriString); + ASSERT_TRUE(res == URI_SUCCESS); + + UriQueryListA * queryList = NULL; + int itemCount = 0; + + res = uriDissectQueryMallocA(&queryList, &itemCount, + uri.query.first, uri.query.afterLast); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(queryList != NULL); + ASSERT_TRUE(itemCount == pairsExpected); + uriFreeQueryListA(queryList); + uriFreeUriMembersA(&uri); + } +} // namespace + +TEST(UriSuite, TestCrashMakeOwnerBug20080207) { + // Testcase by Adrian Manrique + UriParserStateA state; + UriUriA sourceUri; + state.uri = &sourceUri; + const char * const sourceUriString = "http://user:pass@somehost.com:80/"; + if (uriParseUriA(&state, sourceUriString) != 0) { + ASSERT_TRUE(false); + } + if (uriNormalizeSyntaxA(&sourceUri) != 0) { + ASSERT_TRUE(false); + } + uriFreeUriMembersA(&sourceUri); + ASSERT_TRUE(true); +} + +namespace { + void testQueryListHelper(const wchar_t * input, int expectedItemCount) { + int res; + + UriBool spacePlusConversion = URI_TRUE; + UriBool normalizeBreaks = URI_FALSE; + UriBreakConversion breakConversion = URI_BR_DONT_TOUCH; + + int itemCount; + UriQueryListW * queryList; + res = uriDissectQueryMallocExW(&queryList, &itemCount, + input, input + wcslen(input), spacePlusConversion, breakConversion); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(itemCount == expectedItemCount); + ASSERT_TRUE((queryList == NULL) == (expectedItemCount == 0)); + + if (expectedItemCount != 0) { + // First + int charsRequired; + res = uriComposeQueryCharsRequiredExW(queryList, &charsRequired, spacePlusConversion, + normalizeBreaks); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(charsRequired >= (int)wcslen(input)); + + wchar_t * recomposed = new wchar_t[charsRequired + 1]; + int charsWritten; + res = uriComposeQueryExW(recomposed, queryList, charsRequired + 1, + &charsWritten, spacePlusConversion, normalizeBreaks); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(charsWritten <= charsRequired); + ASSERT_TRUE(charsWritten == (int)wcslen(input) + 1); + ASSERT_TRUE(!wcscmp(input, recomposed)); + delete [] recomposed; + + recomposed = NULL; + res = uriComposeQueryMallocW(&recomposed, queryList); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(recomposed != NULL); + ASSERT_TRUE(charsWritten == (int)wcslen(input) + 1); + ASSERT_TRUE(!wcscmp(input, recomposed)); + free(recomposed); + } + + uriFreeQueryListW(queryList); + } +} // namespace + +TEST(UriSuite, QueryList) { + testQueryListHelper(L"one=ONE&two=TWO", 2); + testQueryListHelper(L"one=ONE&two=&three=THREE", 3); + testQueryListHelper(L"one=ONE&two&three=THREE", 3); + testQueryListHelper(L"one=ONE", 1); + testQueryListHelper(L"one", 1); + testQueryListHelper(L"", 0); +} + +namespace { + void testQueryListPairHelper(const char * pair, const char * unescapedKey, + const char * unescapedValue, const char * fixed = NULL) { + int res; + UriQueryListA * queryList; + int itemCount; + + res = uriDissectQueryMallocA(&queryList, &itemCount, pair, pair + strlen(pair)); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(queryList != NULL); + ASSERT_TRUE(itemCount == 1); + ASSERT_TRUE(!strcmp(queryList->key, unescapedKey)); + ASSERT_TRUE(!strcmp(queryList->value, unescapedValue)); + + char * recomposed; + res = uriComposeQueryMallocA(&recomposed, queryList); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(recomposed != NULL); + ASSERT_TRUE(!strcmp(recomposed, (fixed != NULL) ? fixed : pair)); + free(recomposed); + uriFreeQueryListA(queryList); + } +} // namespace + +TEST(UriSuite, TestQueryListPair) { + testQueryListPairHelper("one+two+%26+three=%2B", "one two & three", "+"); + testQueryListPairHelper("one=two=three", "one", "two=three", "one=two%3Dthree"); + testQueryListPairHelper("one=two=three=four", "one", "two=three=four", "one=two%3Dthree%3Dfour"); +} + +TEST(UriSuite, TestQueryDissectionBug3590761) { + int res; + UriQueryListA * queryList; + int itemCount; + const char * const pair = "q=hello&x=&y="; + + res = uriDissectQueryMallocA(&queryList, &itemCount, pair, pair + strlen(pair)); + ASSERT_TRUE(res == URI_SUCCESS); + ASSERT_TRUE(queryList != NULL); + ASSERT_TRUE(itemCount == 3); + + ASSERT_TRUE(!strcmp(queryList->key, "q")); + ASSERT_TRUE(!strcmp(queryList->value, "hello")); + + ASSERT_TRUE(!strcmp(queryList->next->key, "x")); + ASSERT_TRUE(!strcmp(queryList->next->value, "")); + + ASSERT_TRUE(!strcmp(queryList->next->next->key, "y")); + ASSERT_TRUE(!strcmp(queryList->next->next->value, "")); + + ASSERT_TRUE(! queryList->next->next->next); + + uriFreeQueryListA(queryList); +} + +TEST(UriSuite, TestQueryCompositionMathCalc) { + UriQueryListA second = { /*.key =*/ "k2", /*.value =*/ "v2", /*.next =*/ NULL }; + UriQueryListA first = { /*.key =*/ "k1", /*.value =*/ "v1", /*.next =*/ &second }; + + int charsRequired; + ASSERT_TRUE(uriComposeQueryCharsRequiredA(&first, &charsRequired) + == URI_SUCCESS); + + const int FACTOR = 6; /* due to escaping with normalizeBreaks */ + ASSERT_TRUE((unsigned)charsRequired == + FACTOR * strlen(first.key) + 1 + FACTOR * strlen(first.value) + + 1 + + FACTOR * strlen(second.key) + 1 + FACTOR * strlen(second.value) + ); +} + +TEST(UriSuite, TestQueryCompositionMathWriteGoogleAutofuzz113244572) { + UriQueryListA second = { /*.key =*/ "\x11", /*.value =*/ NULL, /*.next =*/ NULL }; + UriQueryListA first = { /*.key =*/ "\x01", /*.value =*/ "\x02", /*.next =*/ &second }; + + const UriBool spaceToPlus = URI_TRUE; + const UriBool normalizeBreaks = URI_FALSE; /* for factor 3 but 6 */ + + const int charsRequired = (3 + 1 + 3) + 1 + (3); + + { + // Minimum space to hold everything fine + const char * const expected = "%01=%02" "&" "%11"; + char dest[charsRequired + 1]; + int charsWritten; + ASSERT_TRUE(uriComposeQueryExA(dest, &first, sizeof(dest), + &charsWritten, spaceToPlus, normalizeBreaks) + == URI_SUCCESS); + ASSERT_TRUE(! strcmp(dest, expected)); + ASSERT_TRUE(charsWritten == strlen(expected) + 1); + } + + { + // Previous math failed to take ampersand into account + char dest[charsRequired + 1 - 1]; + int charsWritten; + ASSERT_TRUE(uriComposeQueryExA(dest, &first, sizeof(dest), + &charsWritten, spaceToPlus, normalizeBreaks) + == URI_ERROR_OUTPUT_TOO_LARGE); + } +} + +TEST(UriSuite, TestFreeCrashBug20080827) { + char const * const sourceUri = "abc"; + char const * const baseUri = "http://www.example.org/"; + + int res; + UriParserStateA state; + UriUriA absoluteDest; + UriUriA relativeSource; + UriUriA absoluteBase; + + state.uri = &relativeSource; + res = uriParseUriA(&state, sourceUri); + ASSERT_TRUE(res == URI_SUCCESS); + + state.uri = &absoluteBase; + res = uriParseUriA(&state, baseUri); + ASSERT_TRUE(res == URI_SUCCESS); + + res = uriRemoveBaseUriA(&absoluteDest, &relativeSource, &absoluteBase, URI_FALSE); + ASSERT_TRUE(res == URI_ERROR_REMOVEBASE_REL_SOURCE); + + uriFreeUriMembersA(&relativeSource); + uriFreeUriMembersA(&absoluteBase); + uriFreeUriMembersA(&absoluteDest); // Crashed here +} + +TEST(UriSuite, TestInvalidInputBug16) { + UriParserStateA stateA; + UriUriA uriA; + stateA.uri = &uriA; + const char * const input = "A>B"; + + const int res = uriParseUriA(&stateA, input); + + ASSERT_TRUE(res == URI_ERROR_SYNTAX); + ASSERT_TRUE(stateA.errorPos == input + 1); + ASSERT_TRUE(stateA.errorCode == URI_ERROR_SYNTAX); /* failed previously */ + + uriFreeUriMembersA(&uriA); +} + +namespace { + void testEqualsHelper(const char * uri_to_test) { + UriParserStateA state; + UriUriA uriOne; + UriUriA uriTwo; + state.uri = &uriOne; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, uri_to_test)); + state.uri = &uriTwo; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, uri_to_test)); + ASSERT_TRUE(URI_TRUE == uriEqualsUriA(&uriOne, &uriTwo)); + uriFreeUriMembersA(&uriOne); + uriFreeUriMembersA(&uriTwo); + } +} // namespace + +TEST(UriSuite, TestEquals) { + testEqualsHelper("http://host"); + testEqualsHelper("http://host:123"); + testEqualsHelper("http://foo:bar@host:123"); + testEqualsHelper("http://foo:bar@host:123/"); + testEqualsHelper("http://foo:bar@host:123/path"); + testEqualsHelper("http://foo:bar@host:123/path?query"); + testEqualsHelper("http://foo:bar@host:123/path?query#fragment"); + + testEqualsHelper("path"); + testEqualsHelper("/path"); + testEqualsHelper("/path/"); + testEqualsHelper("//path/"); + testEqualsHelper("//host"); + testEqualsHelper("//host:123"); +} + +TEST(UriSuite, TestHostTextTerminationIssue15) { + UriParserStateA state; + UriUriA uri; + state.uri = &uri; + + // Empty host and port + const char * const emptyHostWithPortUri = "//:123"; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, emptyHostWithPortUri)); + ASSERT_TRUE(uri.hostText.first == emptyHostWithPortUri + strlen("//")); + ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0); + ASSERT_TRUE(uri.portText.first == emptyHostWithPortUri + + strlen("//:")); + ASSERT_TRUE(uri.portText.afterLast == uri.portText.first + + strlen("123")); + uriFreeUriMembersA(&uri); + + // Non-empty host and port + const char * const hostWithPortUri = "//h:123"; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, hostWithPortUri)); + ASSERT_TRUE(uri.hostText.first == hostWithPortUri + strlen("//")); + ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + + strlen("h")); + ASSERT_TRUE(uri.portText.first == hostWithPortUri + strlen("//h:")); + ASSERT_TRUE(uri.portText.afterLast == uri.portText.first + + strlen("123")); + uriFreeUriMembersA(&uri); + + // Empty host, empty user info + const char * const emptyHostEmptyUserInfoUri = "//@"; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, + emptyHostEmptyUserInfoUri)); + ASSERT_TRUE(uri.userInfo.first == emptyHostEmptyUserInfoUri + + strlen("//")); + ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + 0); + ASSERT_TRUE(uri.hostText.first == emptyHostEmptyUserInfoUri + + strlen("//@")); + ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0); + uriFreeUriMembersA(&uri); + + // Non-empty host, empty user info + const char * const hostEmptyUserInfoUri = "//@h"; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, hostEmptyUserInfoUri)); + ASSERT_TRUE(uri.userInfo.first == hostEmptyUserInfoUri + strlen("//")); + ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + 0); + ASSERT_TRUE(uri.hostText.first == hostEmptyUserInfoUri + + strlen("//@")); + ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + + strlen("h")); + uriFreeUriMembersA(&uri); + + // Empty host, non-empty user info + const char * const emptyHostWithUserInfoUri = "//:@"; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, + emptyHostWithUserInfoUri)); + ASSERT_TRUE(uri.userInfo.first == emptyHostWithUserInfoUri + + strlen("//")); + ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + 1); + ASSERT_TRUE(uri.hostText.first == emptyHostWithUserInfoUri + + strlen("//:@")); + ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0); + uriFreeUriMembersA(&uri); + + // Exact case from issue #15 + const char * const issue15Uri = "//:%aa@"; + ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, issue15Uri)); + ASSERT_TRUE(uri.userInfo.first == issue15Uri + strlen("//")); + ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + + strlen(":%aa")); + ASSERT_TRUE(uri.hostText.first == issue15Uri + strlen("//:%aa@")); + ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0); + uriFreeUriMembersA(&uri); +} + +namespace { + void testCompareRangeHelper(const char * a, const char * b, int expected, bool avoidNullRange = true) { + UriTextRangeA ra; + UriTextRangeA rb; + + if (a) { + ra.first = a; + ra.afterLast = a + strlen(a); + } else { + ra.first = NULL; + ra.afterLast = NULL; + } + + if (b) { + rb.first = b; + rb.afterLast = b + strlen(b); + } else { + rb.first = NULL; + rb.afterLast = NULL; + } + + const int received = uriCompareRangeA( + ((a == NULL) && avoidNullRange) ? NULL : &ra, + ((b == NULL) && avoidNullRange) ? NULL : &rb); + if (received != expected) { + printf("Comparing <%s> to <%s> yields %d, expected %d.\n", + a, b, received, expected); + } + ASSERT_TRUE(received == expected); + } +} // namespace + +TEST(UriSuite, TestRangeComparison) { + testCompareRangeHelper("", "", 0); + testCompareRangeHelper("a", "", 1); + testCompareRangeHelper("", "a", -1); + + testCompareRangeHelper("a", "a", 0); + testCompareRangeHelper("a", "b", -1); + testCompareRangeHelper("b", "a", 1); + + testCompareRangeHelper("a", "aa", -1); + testCompareRangeHelper("aa", "a", 1); + + // Fixed with 0.8.1: + testCompareRangeHelper(NULL, "a", -1); + testCompareRangeHelper("a", NULL, 1); + testCompareRangeHelper(NULL, NULL, 0); + + // Fixed with 0.8.3 + const bool KEEP_NULL_RANGE = false; + const bool AVOID_NULL_RANGE = true; + testCompareRangeHelper(NULL, "", -1, AVOID_NULL_RANGE); + testCompareRangeHelper(NULL, "", -1, KEEP_NULL_RANGE); + testCompareRangeHelper("", NULL, 1, AVOID_NULL_RANGE); + testCompareRangeHelper("", NULL, 1, KEEP_NULL_RANGE); +} + +namespace { + void testRemoveBaseUriHelper(const char * expected, + const char * absSourceStr, + const char * absBaseStr) { + UriParserStateA state; + UriUriA absSource; + UriUriA absBase; + UriUriA dest; + + state.uri = &absSource; + ASSERT_TRUE(uriParseUriA(&state, absSourceStr) == URI_SUCCESS); + + state.uri = &absBase; + ASSERT_TRUE(uriParseUriA(&state, absBaseStr) == URI_SUCCESS); + + ASSERT_TRUE(uriRemoveBaseUriA(&dest, &absSource, &absBase, URI_FALSE) + == URI_SUCCESS); + + int size = 0; + ASSERT_TRUE(uriToStringCharsRequiredA(&dest, &size) == URI_SUCCESS); + char * const buffer = (char *)malloc(size + 1); + ASSERT_TRUE(buffer); + ASSERT_TRUE(uriToStringA(buffer, &dest, size + 1, &size) + == URI_SUCCESS); + if (strcmp(buffer, expected)) { + printf("Expected \"%s\" but got \"%s\"\n", expected, buffer); + ASSERT_TRUE(0); + } + free(buffer); + + uriFreeUriMembersA(&absSource); + uriFreeUriMembersA(&absBase); + uriFreeUriMembersA(&dest); + } +} // namespace + +TEST(UriSuite, TestRangeComparisonRemoveBaseUriIssue19) { + // scheme + testRemoveBaseUriHelper("scheme://host/source", + "scheme://host/source", + "schemelonger://host/base"); + testRemoveBaseUriHelper("schemelonger://host/source", + "schemelonger://host/source", + "scheme://host/base"); + + // hostText + testRemoveBaseUriHelper("//host/source", + "http://host/source", + "http://hostlonger/base"); + testRemoveBaseUriHelper("//hostlonger/source", + "http://hostlonger/source", + "http://host/base"); + + // hostData.ipFuture + testRemoveBaseUriHelper("//[v7.host]/source", + "http://[v7.host]/source", + "http://[v7.hostlonger]/base"); + testRemoveBaseUriHelper("//[v7.hostlonger]/source", + "http://[v7.hostlonger]/source", + "http://host/base"); + + // path + testRemoveBaseUriHelper("path1", + "http://host/path1", + "http://host/path111"); + testRemoveBaseUriHelper("../path1/path2", + "http://host/path1/path2", + "http://host/path111/path222"); + testRemoveBaseUriHelper("path111", + "http://host/path111", + "http://host/path1"); + testRemoveBaseUriHelper("../path111/path222", + "http://host/path111/path222", + "http://host/path1/path2"); + + // Exact issue #19 + testRemoveBaseUriHelper("//example/x/abc", + "http://example/x/abc", + "http://example2/x/y/z"); +} + +TEST(ErrorPosSuite, TestErrorPosIPvFuture) { + UriUriA uri; + const char * errorPos; + + const char * const uriText = "http://[vA.123456"; // missing "]" + EXPECT_EQ(uriParseSingleUriA(&uri, uriText, &errorPos), + URI_ERROR_SYNTAX); + EXPECT_EQ(errorPos, uriText + strlen(uriText)); +} + +TEST(UriParseSingleSuite, Success) { + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriA(&uri, "file:///home/user/song.mp3", NULL), + URI_SUCCESS); + + uriFreeUriMembersA(&uri); +} + +TEST(UriParseSingleSuite, ErrorSyntaxParseErrorSetsErrorPos) { + UriUriA uri; + const char * errorPos; + const char * const uriString = "abc{}def"; + + EXPECT_EQ(uriParseSingleUriA(&uri, uriString, &errorPos), + URI_ERROR_SYNTAX); + EXPECT_EQ(errorPos, uriString + strlen("abc")); + + uriFreeUriMembersA(&uri); +} + +TEST(UriParseSingleSuite, ErrorNullFirstDetected) { + UriUriA uri; + const char * errorPos; + + EXPECT_EQ(uriParseSingleUriExA(&uri, NULL, "notnull", &errorPos), + URI_ERROR_NULL); +} + +TEST(UriParseSingleSuite, ErrorNullAfterLastDetected) { + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriExA(&uri, "foo", NULL, NULL), URI_SUCCESS); + + uriFreeUriMembersA(&uri); +} + +TEST(UriParseSingleSuite, ErrorNullMemoryManagerDetected) { + UriUriA uri; + const char * errorPos; + const char * const uriString = "somethingwellformed"; + + EXPECT_EQ(uriParseSingleUriExMmA(&uri, + uriString, + uriString + strlen(uriString), + &errorPos, NULL), URI_SUCCESS); + + EXPECT_EQ(uriFreeUriMembersMmA(&uri, NULL), URI_SUCCESS); +} + +TEST(FreeUriMembersSuite, MultiFreeWorksFine) { + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriA(&uri, "file:///home/user/song.mp3", NULL), + URI_SUCCESS); + + UriUriA uriBackup = uri; + EXPECT_EQ(memcmp(&uriBackup, &uri, sizeof(UriUriA)), 0); + + uriFreeUriMembersA(&uri); + + // Did some pointers change (to NULL)? + EXPECT_NE(memcmp(&uriBackup, &uri, sizeof(UriUriA)), 0); + + uriFreeUriMembersA(&uri); // second time +} + +namespace { + void testFreeUriMembersFreesHostText(const char *const uriFirst) { // issue #121 + const char *const uriAfterLast = uriFirst + strlen(uriFirst); + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriA(&uri, uriFirst, NULL), URI_SUCCESS); + EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS); + + EXPECT_EQ(uri.owner, URI_TRUE); + EXPECT_TRUE(uri.hostText.first); + EXPECT_TRUE(uri.hostText.afterLast); + EXPECT_NE(uri.hostText.first, uri.hostText.afterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast); + + uriFreeUriMembersA(&uri); + + EXPECT_FALSE(uri.hostText.first); + EXPECT_FALSE(uri.hostText.afterLast); + + uriFreeUriMembersA(&uri); // second time + } +} // namespace + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextIp4) { // issue #121 + testFreeUriMembersFreesHostText("//192.0.2.0"); // RFC 5737 +} + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextIp6) { // issue #121 + testFreeUriMembersFreesHostText("//[2001:db8::]"); // RFC 3849 +} + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextRegname) { // issue #121 + testFreeUriMembersFreesHostText("//host123.test"); // RFC 6761 +} + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextFuture) { // issue #121 + testFreeUriMembersFreesHostText("//[v7.X]"); // arbitrary IPvFuture +} + +TEST(MakeOwnerSuite, MakeOwner) { + const char * const uriString = "scheme://user:pass@[v7.X]:55555/path/../path/?query#fragment"; + UriUriA uri; + char * uriFirst = strdup(uriString); + const size_t uriLen = strlen(uriFirst); + char * uriAfterLast = uriFirst + uriLen; + + EXPECT_EQ(uriParseSingleUriExA(&uri, uriFirst, uriAfterLast, NULL), URI_SUCCESS); + + // After plain parse, all strings should point inside the original URI string + EXPECT_EQ(uri.owner, URI_FALSE); + URI_EXPECT_RANGE_BETWEEN(uri.scheme, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.userInfo, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.hostText, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.hostData.ipFuture, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.portText, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.pathHead->text, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.pathHead->next->text, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.pathHead->next->next->text, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_EMPTY(uri.pathHead->next->next->next->text); + EXPECT_TRUE(uri.pathHead->next->next->next->next == NULL); + URI_EXPECT_RANGE_BETWEEN(uri.query, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_BETWEEN(uri.fragment, uriFirst, uriAfterLast); + + EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS); + + // After making owner, *none* of the strings should point inside the original URI string + EXPECT_EQ(uri.owner, URI_TRUE); + URI_EXPECT_RANGE_OUTSIDE(uri.scheme, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.userInfo, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.hostData.ipFuture, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.portText, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.pathHead->text, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.pathHead->next->text, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.pathHead->next->next->text, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_EMPTY(uri.pathHead->next->next->next->text); + EXPECT_TRUE(uri.pathHead->next->next->next->next == NULL); + URI_EXPECT_RANGE_OUTSIDE(uri.query, uriFirst, uriAfterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.fragment, uriFirst, uriAfterLast); + + // Free originally used memory so we'd get violations on access with ASan + uriAfterLast = NULL; + free(uriFirst); + uriFirst = NULL; + + // Can we recompose the URI without accessing any old freed memory? + int charsRequired; + EXPECT_EQ(uriToStringCharsRequiredA(&uri, &charsRequired), URI_SUCCESS); + EXPECT_TRUE((charsRequired >= 0) && (charsRequired >= static_cast<int>(uriLen))); + char * const uriRemake = new char[charsRequired + 1]; + EXPECT_TRUE(uriRemake != NULL); + EXPECT_EQ(uriToStringA(uriRemake, &uri, charsRequired + 1, NULL), URI_SUCCESS); + EXPECT_TRUE(! strcmp(uriString, uriRemake)); + delete [] uriRemake; + + uriFreeUriMembersA(&uri); +} + +namespace { + void testMakeOwnerCopiesHostText(const char *const uriFirst) { // issue #121 + const char *const uriAfterLast = uriFirst + strlen(uriFirst); + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriA(&uri, uriFirst, NULL), URI_SUCCESS); + EXPECT_EQ(uri.owner, URI_FALSE); + URI_EXPECT_RANGE_BETWEEN(uri.hostText, uriFirst, uriAfterLast); + + EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS); + + EXPECT_EQ(uri.owner, URI_TRUE); + URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast); + + uriFreeUriMembersA(&uri); + uriFreeUriMembersA(&uri); // tried freeing stack pointers before the fix + } +} // namespace + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextIp4) { // issue #121 + testMakeOwnerCopiesHostText("//192.0.2.0"); // RFC 5737 +} + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextIp6) { // issue #121 + testMakeOwnerCopiesHostText("//[2001:db8::]"); // RFC 3849 +} + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextRegname) { // issue #121 + testMakeOwnerCopiesHostText("//host123.test"); // RFC 6761 +} + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextFuture) { // issue #121 + testMakeOwnerCopiesHostText("//[v7.X]"); // arbitrary IPvFuture +} + +TEST(ParseIpFourAddressSuite, FourSaneOctets) { + unsigned char octetOutput[4]; + const char * const ipAddressText = "111.22.3.40"; + const int res = uriParseIpFourAddressA(octetOutput, ipAddressText, + ipAddressText + strlen(ipAddressText)); + EXPECT_EQ(res, URI_SUCCESS); + EXPECT_EQ(octetOutput[0], 111); + EXPECT_EQ(octetOutput[1], 22); + EXPECT_EQ(octetOutput[2], 3); + EXPECT_EQ(octetOutput[3], 40); +} diff --git a/contrib/restricted/uriparser/test/ya.make b/contrib/restricted/uriparser/test/ya.make new file mode 100644 index 0000000000..ae8a32a932 --- /dev/null +++ b/contrib/restricted/uriparser/test/ya.make @@ -0,0 +1,38 @@ +# Generated by devtools/yamaker. + +GTEST(testrunner) + +OWNER( + kikht + shindo + g:cpp-contrib + g:mds +) + +LICENSE( + LGPL-2.1-only AND + LGPL-2.1-or-later +) + +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + +PEERDIR( + contrib/restricted/uriparser +) + +ADDINCL( + contrib/restricted/uriparser +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +SRCS( + FourSuite.cpp + MemoryManagerSuite.cpp + VersionSuite.cpp + test.cpp +) + +END() |