summaryrefslogtreecommitdiff
path: root/core/apps/textedit/textedit.cpp
authorerik <erik>2007-01-26 20:30:32 (UTC)
committer erik <erik>2007-01-26 20:30:32 (UTC)
commitf77da1ae08512b02a3c50a124f823ed77e53dd64 (patch) (unidiff)
treeac7e414aff95348e0bf2fba3f45b2a06a4eb4623 /core/apps/textedit/textedit.cpp
parent4688f98202f590ec6af6c2e66a49dd2f80536083 (diff)
downloadopie-f77da1ae08512b02a3c50a124f823ed77e53dd64.zip
opie-f77da1ae08512b02a3c50a124f823ed77e53dd64.tar.gz
opie-f77da1ae08512b02a3c50a124f823ed77e53dd64.tar.bz2
Both packageslave.cpp and textedit.cpp have instances of possibly exploitable
race conditions associated to files. The big deal is that it is quite typical to use strings of pathnames to track files. But because that does not leverage the filesystem would be attackers may be able to exploit time lags in uses of filesystem functions (like stat and chmod or open) to get files with suspect data into the files that the applications are working with. This commit closes that potential hole even though there are no known exploits. Better safe then sorry. There is no change in the behavior of the apps.
Diffstat (limited to 'core/apps/textedit/textedit.cpp') (more/less context) (show whitespace changes)
-rw-r--r--core/apps/textedit/textedit.cpp9
1 files changed, 3 insertions, 6 deletions
diff --git a/core/apps/textedit/textedit.cpp b/core/apps/textedit/textedit.cpp
index 4bbc62b..1c81a55 100644
--- a/core/apps/textedit/textedit.cpp
+++ b/core/apps/textedit/textedit.cpp
@@ -693,243 +693,240 @@ void TextEdit::openFile( const QString &f ) {
693 switch ( QMessageBox::warning(this,tr("Text Editor"),tr("Text Editor has detected<BR>you selected a <B>.desktop</B>file.<BR>Open<B>.desktop</B> file or <B>linked</B> file?"),tr(".desktop File"),tr("Linked Document"),0,1,1) ) 693 switch ( QMessageBox::warning(this,tr("Text Editor"),tr("Text Editor has detected<BR>you selected a <B>.desktop</B>file.<BR>Open<B>.desktop</B> file or <B>linked</B> file?"),tr(".desktop File"),tr("Linked Document"),0,1,1) )
694 { 694 {
695 case 0: //desktop 695 case 0: //desktop
696 filer = f; 696 filer = f;
697 break; 697 break;
698 case 1: //linked 698 case 1: //linked
699 DocLnk sf(f); 699 DocLnk sf(f);
700 filer = sf.file(); 700 filer = sf.file();
701 break; 701 break;
702 }; 702 };
703 } 703 }
704 else if(fi.baseName().left(1) == "") 704 else if(fi.baseName().left(1) == "")
705 { 705 {
706 odebug << "opening dotfile" << oendl; 706 odebug << "opening dotfile" << oendl;
707 currentFileName=f; 707 currentFileName=f;
708 openDotFile(currentFileName); 708 openDotFile(currentFileName);
709 return; 709 return;
710 } 710 }
711 /* 711 /*
712 * The problem is a file where Config(f).isValid() and it does not 712 * The problem is a file where Config(f).isValid() and it does not
713 * end with .desktop will be treated as desktop file 713 * end with .desktop will be treated as desktop file
714 */ 714 */
715 else if (f.find(".desktop",0,true) != -1 ) 715 else if (f.find(".desktop",0,true) != -1 )
716 { 716 {
717 DocLnk sf(f); 717 DocLnk sf(f);
718 filer = sf.file(); 718 filer = sf.file();
719 if(filer.right(1) == "/") 719 if(filer.right(1) == "/")
720 filer = f; 720 filer = f;
721 721
722 } 722 }
723 else 723 else
724 filer = f; 724 filer = f;
725 725
726 DocLnk nf; 726 DocLnk nf;
727 nf.setType("text/plain"); 727 nf.setType("text/plain");
728 nf.setFile(filer); 728 nf.setFile(filer);
729 currentFileName=filer; 729 currentFileName=filer;
730 730
731 nf.setName(fi.baseName()); 731 nf.setName(fi.baseName());
732 openFile(nf); 732 openFile(nf);
733 733
734 odebug << "openFile string "+currentFileName << oendl; 734 odebug << "openFile string "+currentFileName << oendl;
735 735
736 showEditTools(); 736 showEditTools();
737 // Show filename in caption 737 // Show filename in caption
738 QString name = filer; 738 QString name = filer;
739 int sep = name.findRev( '/' ); 739 int sep = name.findRev( '/' );
740 if ( sep > 0 ) 740 if ( sep > 0 )
741 name = name.mid( sep+1 ); 741 name = name.mid( sep+1 );
742 updateCaption( name ); 742 updateCaption( name );
743} 743}
744 744
745void TextEdit::openFile( const DocLnk &f ) { 745void TextEdit::openFile( const DocLnk &f ) {
746// clear(); 746// clear();
747// bFromDocView = true; 747// bFromDocView = true;
748 FileManager fm; 748 FileManager fm;
749 QString txt; 749 QString txt;
750 currentFileName=f.file(); 750 currentFileName=f.file();
751 odebug << "openFile doclnk " + currentFileName << oendl; 751 odebug << "openFile doclnk " + currentFileName << oendl;
752 if ( !fm.loadFile( f, txt ) ) { 752 if ( !fm.loadFile( f, txt ) ) {
753 // ####### could be a new file 753 // ####### could be a new file
754 odebug << "Cannot open file" << oendl; 754 odebug << "Cannot open file" << oendl;
755 } 755 }
756// fileNew(); 756// fileNew();
757 if ( doc ) 757 if ( doc )
758 delete doc; 758 delete doc;
759 doc = new DocLnk(f); 759 doc = new DocLnk(f);
760 editor->setText(txt); 760 editor->setText(txt);
761 editor->setEdited( false); 761 editor->setEdited( false);
762 edited1=false; 762 edited1=false;
763 edited=false; 763 edited=false;
764 764
765 doc->setName(currentFileName); 765 doc->setName(currentFileName);
766 updateCaption(); 766 updateCaption();
767 setTimer(); 767 setTimer();
768} 768}
769 769
770void TextEdit::showEditTools() { 770void TextEdit::showEditTools() {
771 menu->show(); 771 menu->show();
772 editBar->show(); 772 editBar->show();
773 if(!useSearchBar) 773 if(!useSearchBar)
774 searchBar->hide(); 774 searchBar->hide();
775 else 775 else
776 searchBar->show(); 776 searchBar->show();
777 setWState (WState_Reserved1 ); 777 setWState (WState_Reserved1 );
778} 778}
779 779
780/*! 780/*!
781 unprompted save */ 781 unprompted save */
782bool TextEdit::save() { 782bool TextEdit::save() {
783 QString name, file; 783 QString name, file;
784 odebug << "saveAsFile " + currentFileName << oendl; 784 odebug << "saveAsFile " + currentFileName << oendl;
785 if(currentFileName.isEmpty()) { 785 if(currentFileName.isEmpty()) {
786 saveAs(); 786 saveAs();
787 return false; 787 return false;
788 } 788 }
789 name = currentFileName;
790 if(doc) { 789 if(doc) {
791 file = doc->file(); 790 file = doc->file();
792 odebug << "saver file "+file << oendl; 791 odebug << "saver file "+file << oendl;
793 name = doc->name(); 792 name = doc->name();
794 odebug << "File named "+name << oendl; 793 odebug << "File named "+name << oendl;
795 } else { 794 } else {
796 file = currentFileName; 795 file = currentFileName;
797 name = QFileInfo(currentFileName).baseName(); 796 name = QFileInfo(currentFileName).baseName();
798 } 797 }
799 798
800 QString rt = editor->text(); 799 QString rt = editor->text();
801 if( !rt.isEmpty() ) { 800 if( !rt.isEmpty() ) {
802 if(name.isEmpty()) { 801 if(name.isEmpty()) {
803 saveAs(); 802 saveAs();
804 } else { 803 } else {
805 currentFileName = name; 804 currentFileName = name;
806 odebug << "saveFile "+currentFileName << oendl; 805 odebug << "saveFile "+currentFileName << oendl;
807 806
808 struct stat buf; 807 struct stat buf;
809 mode_t mode; 808 mode_t mode;
810 stat(file.latin1(), &buf); 809 QFile f(file);
810 fstat(f.handle(), &buf);
811 mode = buf.st_mode; 811 mode = buf.st_mode;
812 812
813 if(!fileIs) { 813 if(!fileIs) {
814 doc->setName( name); 814 doc->setName( name);
815 FileManager fm; 815 FileManager fm;
816 if ( !fm.saveFile( *doc, rt ) ) { 816 if ( !fm.saveFile( *doc, rt ) ) {
817 QMessageBox::message(tr("Text Edit"),tr("Save Failed")); 817 QMessageBox::message(tr("Text Edit"),tr("Save Failed"));
818 return false; 818 return false;
819 } 819 }
820 } else { 820 } else {
821 odebug << "regular save file" << oendl; 821 odebug << "regular save file" << oendl;
822 QFile f(file);
823 if( f.open(IO_WriteOnly)) { 822 if( f.open(IO_WriteOnly)) {
824 QCString crt = rt.utf8(); 823 QCString crt = rt.utf8();
825 f.writeBlock(crt,crt.length()); 824 f.writeBlock(crt,crt.length());
826 } else { 825 } else {
827 QMessageBox::message(tr("Text Edit"),tr("Write Failed")); 826 QMessageBox::message(tr("Text Edit"),tr("Write Failed"));
828 return false; 827 return false;
829 } 828 }
830
831 } 829 }
832 editor->setEdited( false); 830 editor->setEdited( false);
833 edited1=false; 831 edited1=false;
834 edited=false; 832 edited=false;
835 if(caption().left(1)=="*") 833 if(caption().left(1)=="*")
836 setCaption(caption().right(caption().length()-1)); 834 setCaption(caption().right(caption().length()-1));
837 835
838 836 fchmod( f.handle(), mode);
839 chmod( file.latin1(), mode);
840 } 837 }
841 return true; 838 return true;
842 } 839 }
843 return false; 840 return false;
844} 841}
845 842
846/*! 843/*!
847 prompted save */ 844 prompted save */
848bool TextEdit::saveAs() { 845bool TextEdit::saveAs() {
849 846
850 if(caption() == tr("Text Editor")) 847 if(caption() == tr("Text Editor"))
851 return false; 848 return false;
852 odebug << "saveAsFile " + currentFileName << oendl; 849 odebug << "saveAsFile " + currentFileName << oendl;
853 850
854 QString rt = editor->text(); 851 QString rt = editor->text();
855 odebug << currentFileName << oendl; 852 odebug << currentFileName << oendl;
856 853
857 if( currentFileName.isEmpty() 854 if( currentFileName.isEmpty()
858 || currentFileName == tr("Unnamed") 855 || currentFileName == tr("Unnamed")
859 || currentFileName == tr("Text Editor")) 856 || currentFileName == tr("Text Editor"))
860 { 857 {
861 odebug << "do silly TT filename thing" << oendl; 858 odebug << "do silly TT filename thing" << oendl;
862 QString pt = rt.simplifyWhiteSpace(); 859 QString pt = rt.simplifyWhiteSpace();
863 int i = pt.find( ' ' ); 860 int i = pt.find( ' ' );
864 QString docname = pt; 861 QString docname = pt;
865 if ( i > 0 ) docname = pt.left( i ); 862 if ( i > 0 ) docname = pt.left( i );
866 863
867 while( docname.startsWith( "." ) ) 864 while( docname.startsWith( "." ) )
868 docname = docname.mid( 1 ); 865 docname = docname.mid( 1 );
869 docname.replace( QRegExp("/"), "_" ); 866 docname.replace( QRegExp("/"), "_" );
870 // Cut the length. Filenames longer than 40 are not helpful 867 // Cut the length. Filenames longer than 40 are not helpful
871 // and something goes wrong when they get too long. 868 // and something goes wrong when they get too long.
872 if ( docname.length() > 40 ) docname = docname.left(40); 869 if ( docname.length() > 40 ) docname = docname.left(40);
873 870
874 if ( docname.isEmpty() ) docname = tr("Unnamed"); 871 if ( docname.isEmpty() ) docname = tr("Unnamed");
875 872
876 if(doc) doc->setName(docname); 873 if(doc) doc->setName(docname);
877 874
878 currentFileName=docname; 875 currentFileName=docname;
879 } 876 }
880 877
881 878
882 QMap<QString, QStringList> map; 879 QMap<QString, QStringList> map;
883 map.insert(tr("All"), QStringList() ); 880 map.insert(tr("All"), QStringList() );
884 QStringList text; 881 QStringList text;
885 text << "text/*"; 882 text << "text/*";
886 map.insert(tr("Text"), text ); 883 map.insert(tr("Text"), text );
887 text << "*"; 884 text << "*";
888 map.insert(tr("All"), text ); 885 map.insert(tr("All"), text );
889 886
890 QFileInfo cuFi( currentFileName); 887 QFileInfo cuFi( currentFileName);
891 QString filee = cuFi.fileName(); 888 QString filee = cuFi.fileName();
892 QString dire = cuFi.dirPath(); 889 QString dire = cuFi.dirPath();
893 if(dire==".") 890 if(dire==".")
894 dire = QPEApplication::documentDir(); 891 dire = QPEApplication::documentDir();
895 892
896 QString str; 893 QString str;
897 if( !featureAutoSave) { 894 if( !featureAutoSave) {
898 str = OFileDialog::getSaveFileName( 2, dire, filee, map); 895 str = OFileDialog::getSaveFileName( 2, dire, filee, map);
899 } else 896 } else
900 str = currentFileName; 897 str = currentFileName;
901 898
902 if(!str.isEmpty()) { 899 if(!str.isEmpty()) {
903 QString fileNm=str; 900 QString fileNm=str;
904 901
905 odebug << "saving filename "+fileNm << oendl; 902 odebug << "saving filename "+fileNm << oendl;
906 QFileInfo fi(fileNm); 903 QFileInfo fi(fileNm);
907 currentFileName=fi.fileName(); 904 currentFileName=fi.fileName();
908 if(doc) 905 if(doc)
909 delete doc; 906 delete doc;
910 907
911 DocLnk nf; 908 DocLnk nf;
912 nf.setType("text/plain"); 909 nf.setType("text/plain");
913 nf.setFile( fileNm); 910 nf.setFile( fileNm);
914 doc = new DocLnk(nf); 911 doc = new DocLnk(nf);
915 odebug << "Saving file as "+currentFileName << oendl; 912 odebug << "Saving file as "+currentFileName << oendl;
916 doc->setName( fi.baseName() ); 913 doc->setName( fi.baseName() );
917 updateCaption( currentFileName); 914 updateCaption( currentFileName);
918 915
919 FileManager fm; 916 FileManager fm;
920 if ( !fm.saveFile( *doc, rt ) ) { 917 if ( !fm.saveFile( *doc, rt ) ) {
921 QMessageBox::message(tr("Text Edit"),tr("Save Failed")); 918 QMessageBox::message(tr("Text Edit"),tr("Save Failed"));
922 return false; 919 return false;
923 } 920 }
924 921
925 if( filePerms ) { 922 if( filePerms ) {
926 filePermissions *filePerm; 923 filePermissions *filePerm;
927 filePerm = new filePermissions(this, tr("Permissions"),true, 0, 924 filePerm = new filePermissions(this, tr("Permissions"),true, 0,
928 (const QString &)fileNm); 925 (const QString &)fileNm);
929 QPEApplication::execDialog( filePerm ); 926 QPEApplication::execDialog( filePerm );
930 927
931 delete filePerm; 928 delete filePerm;
932 } 929 }
933 editor->setEdited( false); 930 editor->setEdited( false);
934 edited1 = false; 931 edited1 = false;
935 edited = false; 932 edited = false;