From 12875949914201cb96eee7b928c0f3a0402c3937 Mon Sep 17 00:00:00 2001 From: Valentin Kuznetsov Date: Sat, 7 Oct 2023 12:10:42 -0400 Subject: [PATCH] Fix issues with malformed query and _id --- web/handlers.go | 9 +++++++-- web/mongo.go | 6 ++++++ web/query.go | 23 ++++++++++++++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/web/handlers.go b/web/handlers.go index 0650f3b..345bfca 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -222,11 +222,16 @@ func SearchHandler(w http.ResponseWriter, r *http.Request) { } // we store all values as lower case and will use lower case in searches query := r.FormValue("query") -// query = strings.ToLower(query) - spec := ParseQuery(query) + // query = strings.ToLower(query) + spec, err := ParseQuery(query) if Config.Verbose > 0 { log.Printf("search query='%s' spec=%+v user=%v", query, spec, user) } + if err != nil { + msg := "unable to parse user query" + handleError(w, r, msg, err) + return + } // check if we use web or cli if client := r.FormValue("client"); client == "cli" { diff --git a/web/mongo.go b/web/mongo.go index b77f16b..fd9c432 100644 --- a/web/mongo.go +++ b/web/mongo.go @@ -210,6 +210,9 @@ func MongoUpsert(dbname, collname string, records []Record) error { // MongoGet records from MongoDB func MongoGet(dbname, collname string, spec bson.M, idx, limit int) []Record { + if Config.Verbose > 1 { + log.Printf("MongoGet spec=%s idx=%d limit=%d", spec, idx, limit) + } out := []Record{} s := _Mongo.Connect() defer s.Close() @@ -267,6 +270,9 @@ func MongoUpdate(dbname, collname string, spec, newdata bson.M) { // MongoCount gets number records from MongoDB func MongoCount(dbname, collname string, spec bson.M) int { + if Config.Verbose > 1 { + log.Printf("MongoCount spec=%s", spec) + } s := _Mongo.Connect() defer s.Close() c := s.DB(dbname).C(collname) diff --git a/web/query.go b/web/query.go index 2753d02..0b28ea9 100644 --- a/web/query.go +++ b/web/query.go @@ -7,6 +7,7 @@ package main import ( "encoding/json" + "errors" "fmt" "log" "strconv" @@ -50,20 +51,27 @@ func convertType(val interface{}) interface{} { // ParseQuery function provides basic parser for user queries and return // results in bson dictionary -func ParseQuery(query string) bson.M { +func ParseQuery(query string) (bson.M, error) { spec := make(bson.M) if strings.TrimSpace(query) == "" { log.Println("WARNING: empty query string") - return nil + return nil, errors.New("empty query") } // support MongoDB specs if strings.Contains(query, "{") { - if err := json.Unmarshal([]byte(query), &spec); err == nil { + err := json.Unmarshal([]byte(query), &spec) + if err == nil { if Config.Verbose > 0 { log.Printf("found bson spec %+v", spec) } - return spec + // adjust query _id to object id type + if val, ok := spec["_id"]; ok { + spec["_id"] = bson.ObjectIdHex(val.(string)) + } + return spec, nil } + log.Printf("ERROR: unable to parse input query '%s' error %v", query, err) + return nil, err } // query as key:value @@ -98,7 +106,7 @@ func ParseQuery(query string) bson.M { // or, query as free text spec["$text"] = bson.M{"$search": query} } - return adjustQuery(spec) + return adjustQuery(spec), nil } // helper function to adjust query keys @@ -109,6 +117,11 @@ func adjustQuery(spec bson.M) bson.M { if strings.HasPrefix(kkk, "$") { continue } + // adjust query _id to object id type + if kkk == "_id" { + nspec["_id"] = bson.ObjectIdHex(val.(string)) + continue + } // look-up appropriate schema key if key, ok := _schemaKeys[strings.ToLower(kkk)]; ok { // create regex for value if it is the string