[Webkit-unassigned] [Bug 148388] We should also store the time information for recent searches
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Thu Oct 8 17:43:04 PDT 2015
https://bugs.webkit.org/show_bug.cgi?id=148388
--- Comment #31 from Zach Li <zacharyli323 at gmail.com> ---
(In reply to comment #29)
> (In reply to comment #28)
> > Comment on attachment 262212 [details]
> > Patch v4
> >
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=262212&action=review
> >
> > Looks generally good, but review- because of the incorrect code to read from
> > disk (see below for details)
>
> Yeah my code is not robust and I am making too many assumptions.
>
> >
> > > Source/WebCore/platform/SearchPopupMenu.h:40
> > > +typedef struct RecentSearchItem {
> > > + RecentSearchItem() { }
> > > +
> > > + RecentSearchItem(const String& searchString, std::chrono::system_clock::time_point time)
> > > + : searchString(searchString), time(time) { }
> > > +
> > > + String searchString;
> > > + std::chrono::system_clock::time_point time;
> > > +} RecentSearchItem;
> >
> > This typedef struct X {} X; pattern is completely unnecessary in C++. Just
> > struct X { } is fine. There is no need to create constructors for a struct
> > like this in modern C++. I also donât think thereâs a good reason to call
> > this searchString and time rather than searchString and searchTime or just
> > string and time. And further, thereâs no reason to call this both recent
> > searches and recent search items. I donât think the word items adds much. So
> > this should be:
> >
> > struct RecentSearch {
> > String string;
> > std::chrono::system_clock::time_point time;
> > };
>
> I was looking at examples of how struct is used in other places in WebKit
> and a lot of them have constructors, so I thought it is a good practice, but
> I will refine the struct declaration.
>
> >
> > > Source/WebCore/platform/win/SearchPopupMenuWin.cpp:94
> > > + searchItems.append(RecentSearchItem((String)(CFStringRef)item, std::chrono::system_clock::time_point::min()));
> >
> > The cast to CFStringRef here is not helpful since item is already a
> > CFStringRef. The C-style cast to String here is not something we normally
> > do. I suggest a C++ style cast. Passing min() here requires a comment; itâs
> > not obvious why tiâs OK. And we should use aggregate syntax for this struct.
> > So please add a comment explaining why min is correct and write something
> > more like this:
> >
> > searchItems.append({ String{ item },
> > std::chrono::system_clock::time_point::min() });
>
> I will add comments to explain why the use of min().
>
> >
> > > Source/WebCore/rendering/RenderSearchField.cpp:94
> > > + m_recentSearches.insert(0, RecentSearchItem(value, std::chrono::system_clock::now()));
> >
> > Please use aggregate syntax rather than constructor syntax:
> >
> > m_recentSearches.insert(0, { value, std::chrono::system_clock::now() });
>
> Will do.
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:52
> > > +static NSMutableDictionary *readSearchFieldRecentSearchesPlist()
> > > +{
> > > + return [[NSMutableDictionary alloc] initWithContentsOfFile:searchFieldRecentSearchesPlistPath()];
> > > +}
> >
> > This function is dangerous. It returns a newly created Objective-C object,
> > but doesnât use autorelease, nor wrap the pointer in a RetainPtr, nor does
> > it follow the create/copy rule for naming functions that create new objects
> > without autoreleasing them. I suggest using RetainPtr for the result here so
> > we donât leak memory.
>
> Nice catch. Will take care of the memory management.
>
> >
> > Iâm also not sure that [NSMutableDictionary initWithContentsOfFile:] is safe
> > to use on an untrusted file. We need to instead use an appropriate API that
> > doesnât allow objects of arbitrary classes.
Dan and I looked at the implementation of [NSMutableDictionary initWithContentsOfFile:], it will return nil when the object is not a dictionary. It also should return all the container classes in mutable form. But I will check if the dictionary is mutable before modifying it.
>
> When you say "arbitrary classes", do you mean the plist should be a
> dictionary, not an array or a string, etc.?
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:78
> > > + NSMutableDictionary *recentSearchesPlist = readSearchFieldRecentSearchesPlist();
> >
> > Here we leak the contents of this file. Thatâs why we need to use a
> > RetainPtr or autorelease.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:80
> > > + [recentSearchesPlist[itemsKey] removeObjectForKey:name];
> >
> > This wonât compile when targeting older versions of OS X, so we need to use
> > objectForKey here instead of array subscripting syntax.
> >
> > This code assumes that type of the key in the property list that we read in
> > from will be a mutable dictionary and we can call removeObjectForKey on it.
> > We donât have a guarantee of that. We need to check the type of the object
> > to see that itâs a dictionary before modifying it, and we also need to make
> > a mutable copy of the dictionary unless we are using an API that guarantees
> > that any dictionaries it creates when reading the file are created mutable,
> > which we currently are not doing.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:84
> > > + NSTimeInterval timeInterval = duration_cast<duration<double>>(searchItem.time.time_since_epoch()).count();
> >
> > Iâd like to see a helper function template to convert a duration object into
> > an NSDate rather than writing this out here. Itâs also not good that the
> > code that creates the interval since 1970 is on a different line than the
> > code that create the NSDate.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:88
> > > + NSDictionary *recentSearch = @{
> > > + searchStringKey: searchItem.searchString,
> > > + dateKey: [NSDate dateWithTimeIntervalSince1970:timeInterval]
> > > + };
> >
> > Iâm pretty sure that the dictionary literal syntax is not supported in all
> > tools that we use for the versions of OS X that we currently target with
> > WebKit. This might need to use method calls instead. Unless I am mistaken.
There are instances in WebKit where we use the dictionary literal syntax, but because
I had to use method calls in some places, I just used method calls instead of the
dictionary literal syntax in all the places.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:94
> > > + [recentSearchesPlist[itemsKey] setObject:@{ searchesKey: items.get() } forKey:name];
> >
> > Same problem here as in the removeObjectForKey: call above, and same issue
> > with literals.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:96
> > > + recentSearchesPlist = [@{ itemsKey: @{ name: @{ searchesKey: items.get() } } } mutableCopy];
> >
> > Same issue with literals. Doesnât seem to good to make a mutable copy here.
> > Wasteful.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:99
> > > + [recentSearchesPlist writeToFile:searchFieldRecentSearchesPlistPath() atomically:YES];
> >
> > Using atomically:YES is costly in performance and in NAND life. We should be
> > sure this is necessary.
I decided to use atomically:NO in the end since I added all these checks when reading the plist from the disk so even if the file is corrupted, it shouldn't be a big concern and we avoid the costly performance issue by using atomically:YES.
>
> I am setting it to YES because I am afraid the file might be corrupted while
> writing. With my previous approach of reading the plist from disk, I assume
> the file should be in the expected format. Your suggestions above will
> alleviate the problem. But I still think we should write atomically, what do
> you think?
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:112
> > > + NSArray *recentSearches = [[[recentSearchesPlist objectForKey:itemsKey] objectForKey:name] objectForKey:searchesKey];
> >
> > Same comment about calling objectForKey: on an object of unknown type as
> > above.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:115
> > > + system_clock::time_point searchItemTime = system_clock::time_point(duration_cast<system_clock::duration>(duration<double>(dynamic_objc_cast<NSDate>(item[dateKey]).timeIntervalSince1970)));
> >
> > Same comment about using helper functions to convert between NSDate and time
> > points as above.
>
> Will fix.
>
> >
> > > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:116
> > > + searchItems.append(WebCore::RecentSearchItem((String)item[searchStringKey], searchItemTime));
> >
> > Same comment about aggregate syntax.
>
> Will fix.
>
> >
> > > Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm:38
> > > +static NSString * const dateKey = @"date";
> > > +static NSString * const itemsKey = @"items";
> > > +static NSString * const searchesKey = @"searches";
> > > +static NSString * const searchStringKey = @"searchString";
> >
> > Seems quite bad to literally have copied and pasted code for WebKit 1 and
> > WebKit 2. Please find a way to share more of the code.
>
> Will do.
>
> Thanks for the review!
(In reply to comment #28)
> Comment on attachment 262212 [details]
> Patch v4
>
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=262212&action=review
>
> Looks generally good, but review- because of the incorrect code to read from
> disk (see below for details)
>
> > Source/WebCore/platform/SearchPopupMenu.h:40
> > +typedef struct RecentSearchItem {
> > + RecentSearchItem() { }
> > +
> > + RecentSearchItem(const String& searchString, std::chrono::system_clock::time_point time)
> > + : searchString(searchString), time(time) { }
> > +
> > + String searchString;
> > + std::chrono::system_clock::time_point time;
> > +} RecentSearchItem;
>
> This typedef struct X {} X; pattern is completely unnecessary in C++. Just
> struct X { } is fine. There is no need to create constructors for a struct
> like this in modern C++. I also donât think thereâs a good reason to call
> this searchString and time rather than searchString and searchTime or just
> string and time. And further, thereâs no reason to call this both recent
> searches and recent search items. I donât think the word items adds much. So
> this should be:
>
> struct RecentSearch {
> String string;
> std::chrono::system_clock::time_point time;
> };
>
> > Source/WebCore/platform/win/SearchPopupMenuWin.cpp:94
> > + searchItems.append(RecentSearchItem((String)(CFStringRef)item, std::chrono::system_clock::time_point::min()));
>
> The cast to CFStringRef here is not helpful since item is already a
> CFStringRef. The C-style cast to String here is not something we normally
> do. I suggest a C++ style cast. Passing min() here requires a comment; itâs
> not obvious why tiâs OK. And we should use aggregate syntax for this struct.
> So please add a comment explaining why min is correct and write something
> more like this:
>
> searchItems.append({ String{ item },
> std::chrono::system_clock::time_point::min() });
>
> > Source/WebCore/rendering/RenderSearchField.cpp:94
> > + m_recentSearches.insert(0, RecentSearchItem(value, std::chrono::system_clock::now()));
>
> Please use aggregate syntax rather than constructor syntax:
>
> m_recentSearches.insert(0, { value, std::chrono::system_clock::now() });
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:52
> > +static NSMutableDictionary *readSearchFieldRecentSearchesPlist()
> > +{
> > + return [[NSMutableDictionary alloc] initWithContentsOfFile:searchFieldRecentSearchesPlistPath()];
> > +}
>
> This function is dangerous. It returns a newly created Objective-C object,
> but doesnât use autorelease, nor wrap the pointer in a RetainPtr, nor does
> it follow the create/copy rule for naming functions that create new objects
> without autoreleasing them. I suggest using RetainPtr for the result here so
> we donât leak memory.
>
> Iâm also not sure that [NSMutableDictionary initWithContentsOfFile:] is safe
> to use on an untrusted file. We need to instead use an appropriate API that
> doesnât allow objects of arbitrary classes.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:78
> > + NSMutableDictionary *recentSearchesPlist = readSearchFieldRecentSearchesPlist();
>
> Here we leak the contents of this file. Thatâs why we need to use a
> RetainPtr or autorelease.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:80
> > + [recentSearchesPlist[itemsKey] removeObjectForKey:name];
>
> This wonât compile when targeting older versions of OS X, so we need to use
> objectForKey here instead of array subscripting syntax.
>
> This code assumes that type of the key in the property list that we read in
> from will be a mutable dictionary and we can call removeObjectForKey on it.
> We donât have a guarantee of that. We need to check the type of the object
> to see that itâs a dictionary before modifying it, and we also need to make
> a mutable copy of the dictionary unless we are using an API that guarantees
> that any dictionaries it creates when reading the file are created mutable,
> which we currently are not doing.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:84
> > + NSTimeInterval timeInterval = duration_cast<duration<double>>(searchItem.time.time_since_epoch()).count();
>
> Iâd like to see a helper function template to convert a duration object into
> an NSDate rather than writing this out here. Itâs also not good that the
> code that creates the interval since 1970 is on a different line than the
> code that create the NSDate.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:88
> > + NSDictionary *recentSearch = @{
> > + searchStringKey: searchItem.searchString,
> > + dateKey: [NSDate dateWithTimeIntervalSince1970:timeInterval]
> > + };
>
> Iâm pretty sure that the dictionary literal syntax is not supported in all
> tools that we use for the versions of OS X that we currently target with
> WebKit. This might need to use method calls instead. Unless I am mistaken.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:94
> > + [recentSearchesPlist[itemsKey] setObject:@{ searchesKey: items.get() } forKey:name];
>
> Same problem here as in the removeObjectForKey: call above, and same issue
> with literals.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:96
> > + recentSearchesPlist = [@{ itemsKey: @{ name: @{ searchesKey: items.get() } } } mutableCopy];
>
> Same issue with literals. Doesnât seem to good to make a mutable copy here.
> Wasteful.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:99
> > + [recentSearchesPlist writeToFile:searchFieldRecentSearchesPlistPath() atomically:YES];
>
> Using atomically:YES is costly in performance and in NAND life. We should be
> sure this is necessary.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:112
> > + NSArray *recentSearches = [[[recentSearchesPlist objectForKey:itemsKey] objectForKey:name] objectForKey:searchesKey];
>
> Same comment about calling objectForKey: on an object of unknown type as
> above.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:115
> > + system_clock::time_point searchItemTime = system_clock::time_point(duration_cast<system_clock::duration>(duration<double>(dynamic_objc_cast<NSDate>(item[dateKey]).timeIntervalSince1970)));
>
> Same comment about using helper functions to convert between NSDate and time
> points as above.
>
> > Source/WebKit/mac/WebCoreSupport/SearchPopupMenuMac.mm:116
> > + searchItems.append(WebCore::RecentSearchItem((String)item[searchStringKey], searchItemTime));
>
> Same comment about aggregate syntax.
>
> > Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm:38
> > +static NSString * const dateKey = @"date";
> > +static NSString * const itemsKey = @"items";
> > +static NSString * const searchesKey = @"searches";
> > +static NSString * const searchStringKey = @"searchString";
>
> Seems quite bad to literally have copied and pasted code for WebKit 1 and
> WebKit 2. Please find a way to share more of the code.
--
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20151009/54e376c1/attachment-0001.html>
More information about the webkit-unassigned
mailing list