Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com

fix: add bounds validation and ApplyWithVersion to OT engine

+39 -1
+39 -1
internal/collaboration/ot.go
··· 19 19 From int `json:"from"` 20 20 To int `json:"to"` 21 21 Insert string `json:"insert"` 22 + // Author is set by the client and used for logging/debugging purposes 23 + // to identify which user performed an operation 22 24 Author string `json:"author"` 23 25 } 24 26 ··· 26 28 ot.mu.Lock() 27 29 defer ot.mu.Unlock() 28 30 31 + if op.From < 0 { 32 + op.From = 0 33 + } 34 + if op.To < 0 { 35 + op.To = 0 36 + } 37 + if op.From > len(ot.documentText) { 38 + op.From = len(ot.documentText) 39 + } 29 40 if op.To > len(ot.documentText) { 30 41 op.To = len(ot.documentText) 31 42 } 43 + if op.From > op.To { 44 + return ot.documentText 45 + } 46 + 47 + newText := ot.documentText[:op.From] + op.Insert + ot.documentText[op.To:] 48 + ot.documentText = newText 49 + ot.version++ 50 + 51 + return ot.documentText 52 + } 53 + 54 + func (ot *OTEngine) ApplyWithVersion(op Operation) (string, int) { 55 + ot.mu.Lock() 56 + defer ot.mu.Unlock() 57 + 58 + if op.From < 0 { 59 + op.From = 0 60 + } 61 + if op.To < 0 { 62 + op.To = 0 63 + } 32 64 if op.From > len(ot.documentText) { 33 65 op.From = len(ot.documentText) 34 66 } 67 + if op.To > len(ot.documentText) { 68 + op.To = len(ot.documentText) 69 + } 70 + if op.From > op.To { 71 + return ot.documentText, ot.version 72 + } 35 73 36 74 newText := ot.documentText[:op.From] + op.Insert + ot.documentText[op.To:] 37 75 ot.documentText = newText 38 76 ot.version++ 39 77 40 - return ot.documentText 78 + return ot.documentText, ot.version 41 79 } 42 80 43 81 func (ot *OTEngine) GetText() string {