diff --git a/Fix-Gcc-warnings-for-strncpy-and-strncat.patch b/Fix-Gcc-warnings-for-strncpy-and-strncat.patch new file mode 100644 index 0000000..812a391 --- /dev/null +++ b/Fix-Gcc-warnings-for-strncpy-and-strncat.patch @@ -0,0 +1,81 @@ +From 22ad4f7200a56da969e9296d8fecf2f0b8368afc Mon Sep 17 00:00:00 2001 +From: Dan Yeaw +Date: Mon, 23 Dec 2019 15:31:04 -0500 +Subject: [PATCH] Bootloader: Fix GCC warnings for strncpy and strncat. + +Fixes Issue #4196. GCC 8.1 and later added checks to prevent using +strncpy and strncat with the bounds depending on the length of the +source str. In order to fix this, a few approaches were made: +1. Where guards already existed to ensure that added paths weren't +larger than the PATH_MAX, changed to strcpy / strcat which don't take a +length parameter. +2. Where path length checks didn't exist, set the bounds of the strncpy +and strncat to PATH_MAX. + +Signed-off-by: Dan Yeaw +--- + bootloader/src/pyi_path.c | 7 ++++--- + bootloader/src/pyi_pythonlib.c | 12 ++++++------ + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/bootloader/src/pyi_path.c b/bootloader/src/pyi_path.c +index a449f79..d36e3d2 100644 +--- a/bootloader/src/pyi_path.c ++++ b/bootloader/src/pyi_path.c +@@ -56,7 +56,7 @@ pyi_path_dirname(char *result, const char *path) + char *match = NULL; + + /* Copy path to result and then just write '\0' to the place with path separator. */ +- strncpy(result, path, strlen(path) + 1); ++ strncpy(result, path, PATH_MAX); + /* Remove separator from the end. */ + len = strlen(result); + +@@ -143,7 +143,7 @@ pyi_path_join(char *result, const char *path1, const char *path2) + memset(result, 0, PATH_MAX); + } + /* Copy path1 to result without null terminator */ +- strncpy(result, path1, strlen(path1)); ++ strcpy(result, path1); + /* Append trailing slash if missing. */ + len = strlen(result); + +@@ -156,7 +156,8 @@ pyi_path_join(char *result, const char *path1, const char *path2) + + if (path2[len - 1] == PYI_SEP) { + /* Append path2 without slash. */ +- strncat(result, path2, len - 2); ++ strcat(result, path2); ++ result[strlen(result) - 1] = PYI_NULLCHAR; + } + else { + /* path2 does not end with slash. */ +diff --git a/bootloader/src/pyi_pythonlib.c b/bootloader/src/pyi_pythonlib.c +index ee4b3b2..d90c239 100644 +--- a/bootloader/src/pyi_pythonlib.c ++++ b/bootloader/src/pyi_pythonlib.c +@@ -480,15 +480,15 @@ pyi_pylib_start_python(ARCHIVE_STATUS *status) + /* Set sys.path */ + if (is_py2) { + /* sys.path = [mainpath] */ +- strncpy(pypath, status->mainpath, strlen(status->mainpath)); ++ strncpy(pypath, status->mainpath, PATH_MAX); + } + else { + /* sys.path = [base_library, mainpath] */ +- strncpy(pypath, status->mainpath, strlen(status->mainpath)); +- strncat(pypath, PYI_SEPSTR, strlen(PYI_SEPSTR)); +- strncat(pypath, "base_library.zip", strlen("base_library.zip")); +- strncat(pypath, PYI_PATHSEPSTR, strlen(PYI_PATHSEPSTR)); +- strncat(pypath, status->mainpath, strlen(status->mainpath)); ++ strncpy(pypath, status->mainpath, PATH_MAX); ++ strncat(pypath, PYI_SEPSTR, PATH_MAX); ++ strncat(pypath, "base_library.zip", PATH_MAX); ++ strncat(pypath, PYI_PATHSEPSTR, PATH_MAX); ++ strncat(pypath, status->mainpath, PATH_MAX); + }; + + /* +-- +2.23.0 + diff --git a/PyInstaller-3.6.tar.gz b/PyInstaller-3.6.tar.gz new file mode 100644 index 0000000..b0baa1c Binary files /dev/null and b/PyInstaller-3.6.tar.gz differ diff --git a/Reimplement-pyi-search-path-using-strtok.patch b/Reimplement-pyi-search-path-using-strtok.patch new file mode 100644 index 0000000..dbd492a --- /dev/null +++ b/Reimplement-pyi-search-path-using-strtok.patch @@ -0,0 +1,63 @@ +From a95fbb0f497680cce0a097aa3a143e84943b903f Mon Sep 17 00:00:00 2001 +From: Hartmut Goebel +Date: Sun, 3 May 2020 15:26:43 +0200 +Subject: [PATCH] Bootloader: Reimplement pyi_search_path using strtok(). + +This avoids some places where we need to cope with strncpy(= and related. Also +the implementation becomes much simpler. +--- + bootloader/src/pyi_path.c | 34 +++++++--------------------------- + 1 file changed, 7 insertions(+), 27 deletions(-) + +diff --git a/bootloader/src/pyi_path.c b/bootloader/src/pyi_path.c +index 8736de8cc5..fb417e9269 100644 +--- a/bootloader/src/pyi_path.c ++++ b/bootloader/src/pyi_path.c +@@ -205,40 +205,20 @@ pyi_path_exists(char * path) + int + pyi_search_path(char * result, const char * appname) + { +- char * path = pyi_getenv("PATH"); +- char dirname[PATH_MAX + 1]; +- char filename[PATH_MAX + 1]; ++ char *path = pyi_getenv("PATH"); // returns a copy ++ char *dirname; + + if (NULL == path) { + return -1; + } + +- while (1) { +- char *delim = strchr(path, PYI_PATHSEP); +- +- if (delim) { +- size_t len = delim - path; +- +- if (len > PATH_MAX) { +- len = PATH_MAX; +- } +- strncpy(dirname, path, len); +- *(dirname + len) = '\0'; +- } +- else { /* last $PATH element */ +- strncpy(dirname, path, PATH_MAX); +- } +- pyi_path_join(filename, dirname, appname); +- +- if (pyi_path_exists(filename)) { +- strncpy(result, filename, PATH_MAX); ++ dirname = strtok(path, PYI_PATHSEPSTR); ++ while (dirname != NULL) { ++ pyi_path_join(result, dirname, appname); ++ if (pyi_path_exists(result)) { + return 0; + } +- +- if (!delim) { +- break; +- } +- path = delim + 1; ++ dirname = strtok(NULL, PYI_PATHSEPSTR); + } + return -1; + } diff --git a/Use-snprintf-to-simplify-some-string-len.patch b/Use-snprintf-to-simplify-some-string-len.patch new file mode 100644 index 0000000..f0a7fa3 --- /dev/null +++ b/Use-snprintf-to-simplify-some-string-len.patch @@ -0,0 +1,208 @@ +From b4c0d01e751975090fa7346a2a71dd778c3b412c Mon Sep 17 00:00:00 2001 +From: Hartmut Goebel +Date: Sun, 3 May 2020 15:43:52 +0200 +Subject: [PATCH] Bootloader: Use snprintf() to simplify some string length + checks. + +Instead of copying strings and checking whether the string si terminated with +a Null bytes, use snprintf, which tells how much space the new string would +have taken and compare this to the available space. + +Since snprintf() add some overhead, This code might be a bit less efficient. +But this sie the bootloader, and most of the functions are called once only. +--- + bootloader/src/pyi_archive.c | 21 ++++++++------------- + bootloader/src/pyi_launch.c | 27 +++++++++------------------ + bootloader/src/pyi_main.c | 4 ++-- + bootloader/src/pyi_path.c | 3 +-- + bootloader/src/pyi_pythonlib.c | 14 +++++++++----- + bootloader/src/pyi_utils.c | 7 ++----- + 6 files changed, 31 insertions(+), 45 deletions(-) + +diff --git a/bootloader/src/pyi_archive.c b/bootloader/src/pyi_archive.c +index ed886e09fb..32b129fb98 100644 +--- a/bootloader/src/pyi_archive.c ++++ b/bootloader/src/pyi_archive.c +@@ -455,28 +455,23 @@ int + pyi_arch_set_paths(ARCHIVE_STATUS *status, char const * archivePath, + char const * archiveName) + { +- size_t pathlen, namelen; +- +- pathlen = strnlen(archivePath, PATH_MAX); +- namelen = strnlen(archiveName, PATH_MAX); +- +- if (pathlen+namelen+1 > PATH_MAX) { +- return -1; ++ /* Set homepath to where the archive is */ ++ if (snprintf(status->homepath, PATH_MAX, "%s", archivePath) >= PATH_MAX) { ++ return -1; + } + + /* Get the archive Path */ +- strcpy(status->archivename, archivePath); +- strcat(status->archivename, archiveName); +- +- /* Set homepath to where the archive is */ +- strcpy(status->homepath, archivePath); ++ if (snprintf(status->archivename, PATH_MAX, ++ "%s%s", archivePath, archiveName) >= PATH_MAX) { ++ return -1; ++ } + + /* + * Initial value of mainpath is homepath. It might be overriden + * by temppath if it is available. + */ + status->has_temp_directory = false; +- strcpy(status->mainpath, status->homepath); ++ strcpy(status->mainpath, status->homepath); // homepath fits into PATH_MAX + + return 0; + } +diff --git a/bootloader/src/pyi_launch.c b/bootloader/src/pyi_launch.c +index 3517be6353..432a43416f 100644 +--- a/bootloader/src/pyi_launch.c ++++ b/bootloader/src/pyi_launch.c +@@ -79,15 +79,13 @@ checkFile(char *buf, const char *fmt, ...) + static int + splitName(char *path, char *filename, const char *item) + { +- char name[PATH_MAX + 1]; ++ char name[PATH_MAX]; + + VS("LOADER: Splitting item into path and filename\n"); +- strncpy(name, item, PATH_MAX + 1); +- +- if (name[PATH_MAX] != '\0') { ++ if (snprintf(name, PATH_MAX, "%s", item) >= PATH_MAX) { + return -1; + } +- ++ // `name` fits into PATH_MAX, so will all substrings + strcpy(path, strtok(name, ":")); + strcpy(filename, strtok(NULL, ":")); + +@@ -148,13 +146,11 @@ _get_archive(ARCHIVE_STATUS *archive_pool[], const char *path) + return NULL; + } + +- strncpy(archive->archivename, path, PATH_MAX); +- strncpy(archive->homepath, archive_pool[SELF]->homepath, PATH_MAX); +- strncpy(archive->temppath, archive_pool[SELF]->temppath, PATH_MAX); +- +- if (archive->archivename[PATH_MAX-1] != '\0' +- || archive->homepath[PATH_MAX-1] != '\0' +- || archive->temppath[PATH_MAX-1] != '\0') { ++ if ((snprintf(archive->archivename, PATH_MAX, "%s", path) >= PATH_MAX) || ++ (snprintf(archive->homepath, PATH_MAX, "%s", ++ archive_pool[SELF]->homepath) >= PATH_MAX) || ++ (snprintf(archive->temppath, PATH_MAX, "%s", ++ archive_pool[SELF]->temppath) >= PATH_MAX)) { + FATALERROR("Archive path exceeds PATH_MAX\n"); + free(archive); + return NULL; +@@ -369,7 +365,6 @@ pyi_launch_run_scripts(ARCHIVE_STATUS *status) + { + unsigned char *data; + char buf[PATH_MAX]; +- size_t namelen; + TOC * ptoc = status->tocbuff; + PyObject *__main__; + PyObject *__file__; +@@ -400,14 +395,10 @@ pyi_launch_run_scripts(ARCHIVE_STATUS *status) + data = pyi_arch_extract(status, ptoc); + /* Set the __file__ attribute within the __main__ module, + * for full compatibility with normal execution. */ +- namelen = strnlen(ptoc->name, PATH_MAX); +- if (namelen >= PATH_MAX-strlen(".py")-1) { ++ if (snprintf(buf, PATH_MAX, "%s.py", ptoc->name) >= PATH_MAX) { + FATALERROR("Name exceeds PATH_MAX\n"); + return -1; + } +- +- strcpy(buf, ptoc->name); +- strcat(buf, ".py"); + VS("LOADER: Running %s\n", buf); + + if (is_py2) { +diff --git a/bootloader/src/pyi_main.c b/bootloader/src/pyi_main.c +index 02b1bec5dc..472cd1ae9a 100644 +--- a/bootloader/src/pyi_main.c ++++ b/bootloader/src/pyi_main.c +@@ -126,8 +126,8 @@ pyi_main(int argc, char * argv[]) + * we pass it through status variable + */ + if (strcmp(homepath, extractionpath) != 0) { +- strncpy(archive_status->temppath, extractionpath, PATH_MAX); +- if (archive_status->temppath[PATH_MAX-1] != '\0') { ++ if (snprintf(archive_status->temppath, PATH_MAX, ++ "%s", extractionpath) >= PATH_MAX) { + VS("LOADER: temppath exceeds PATH_MAX\n"); + return -1; + } +diff --git a/bootloader/src/pyi_path.c b/bootloader/src/pyi_path.c +index fb417e9269..6ed252ffab 100644 +--- a/bootloader/src/pyi_path.c ++++ b/bootloader/src/pyi_path.c +@@ -286,8 +286,7 @@ pyi_path_executable(char *execfile, const char *appname) + if (-1 == result) { + /* Searching $PATH failed, user is crazy. */ + VS("LOADER: Searching $PATH failed for %s", appname); +- strncpy(buffer, appname, PATH_MAX); +- if (buffer[PATH_MAX-1] != '\0') { ++ if (snprintf(buffer, PATH_MAX, "%s", "appname") >= PATH_MAX) { + VS("LOADER: Appname too large %s\n", appname); + return -1; + } +diff --git a/bootloader/src/pyi_pythonlib.c b/bootloader/src/pyi_pythonlib.c +index caffcd6daa..8144885b17 100644 +--- a/bootloader/src/pyi_pythonlib.c ++++ b/bootloader/src/pyi_pythonlib.c +@@ -414,18 +414,16 @@ pyi_pylib_start_python(ARCHIVE_STATUS *status) + }; + + /* Set sys.path */ +- if (is_py2) { +- /* sys.path = [mainpath] */ +- strncpy(pypath, status->mainpath, PATH_MAX); +- } +- else { +- /* sys.path = [base_library, mainpath] */ ++ /* sys.path = [base_library, mainpath] */ +- strncpy(pypath, status->mainpath, PATH_MAX); +- strncat(pypath, PYI_SEPSTR, PATH_MAX); +- strncat(pypath, "base_library.zip", PATH_MAX); +- strncat(pypath, PYI_PATHSEPSTR, PATH_MAX); +- strncat(pypath, status->mainpath, PATH_MAX); +- }; ++ if (snprintf(pypath, sizeof pypath, "%s%cbase_library.zip%c%s", ++ status->mainpath, PYI_SEP, PYI_PATHSEP, status->mainpath) ++ >= sizeof pypath) { ++ // This should never happen, since mainpath is < PATH_MAX and pypath is ++ // huge enough ++ FATALERROR("sys.path (based on %s) exceeds buffer[%d] space\n", ++ status->mainpath, sizeof pypath); ++ return -1; ++ } + + /* + * On Python 3, we must set sys.path to have base_library.zip before +diff --git a/bootloader/src/pyi_utils.c b/bootloader/src/pyi_utils.c +index e18d611f26..0c89975908 100644 +--- a/bootloader/src/pyi_utils.c ++++ b/bootloader/src/pyi_utils.c +@@ -557,11 +557,8 @@ pyi_open_target(const char *path, const char* name_) + char *dir; + size_t len; + +- strncpy(fnm, path, PATH_MAX); +- strncpy(name, name_, PATH_MAX); +- +- /* Check if the path names could be copied */ +- if (fnm[PATH_MAX-1] != '\0' || name[PATH_MAX-1] != '\0') { ++ if (snprintf(fnm, PATH_MAX, "%s", path) >= PATH_MAX || ++ snprintf(name, PATH_MAX, "%s", name_) >= PATH_MAX) { + return NULL; + } + diff --git a/python-pyinstaller.spec b/python-pyinstaller.spec new file mode 100644 index 0000000..8be38d4 --- /dev/null +++ b/python-pyinstaller.spec @@ -0,0 +1,80 @@ +%global _empty_manifest_terminate_build 0 +Name: python-pyinstaller +Version: 3.6 +Release: 1 +Summary: PyInstaller bundles a Python application and all its dependencies into a single package. +License: GPL license with a special exception which allows to use PyInstaller to build and distribute non-free programs (including commercial ones) +URL: http://www.pyinstaller.org +Source0: https://files.pythonhosted.org/packages/3c/c9/c3f9bc64eb11eee6a824686deba6129884c8cbdf70e750661773b9865ee0/PyInstaller-%{version}.tar.gz +Patch6000: Fix-Gcc-warnings-for-strncpy-and-strncat.patch +Patch6001: Reimplement-pyi-search-path-using-strtok.patch +Patch6002: Use-snprintf-to-simplify-some-string-len.patch +BuildRequires: python3-devel python3-setuptools zlib-devel + +%description +PyInstaller bundles a Python application and all its dependencies into a single +package. The user can run the packaged app without installing a Python +interpreter or any modules. + +%package -n python3-pyinstaller +Summary: PyInstaller bundles a Python application and all its dependencies into a single package. +Provides: python-PyInstaller +BuildRequires: python3-devel python3-setuptools + +%description -n python3-pyinstaller +PyInstaller bundles a Python application and all its dependencies into a single +package. The user can run the packaged app without installing a Python +interpreter or any modules. + +%package help +Summary: Development documents and examples for PyInstaller +Provides: python3-PyInstaller-doc +%description help +PyInstaller bundles a Python application and all its dependencies into a single +package. The user can run the packaged app without installing a Python +interpreter or any modules. + +%prep +%autosetup -n PyInstaller-%{version} -p1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-pyinstaller -f filelist.lst +%dir %{python3_sitelib}/* +%exclude %{python3_sitelib}/PyInstaller/bootloader/{D*,W*,*32*,Linux-64bit} + +%files help -f doclist.lst +%{_pkgdocdir} + +%changelog +* Mon Jun 22 2020 Python_Bot +- Package Spec generated diff --git a/python-pyinstaller.yaml b/python-pyinstaller.yaml new file mode 100644 index 0000000..7ca096d --- /dev/null +++ b/python-pyinstaller.yaml @@ -0,0 +1,4 @@ +version_control: pypi +src_repo: PyInstaller +tag_prefix: "v" +seperator: ""