RU.GOLDED --------------- < Пред. | След. > -- < @ > -- < Сообщ. > -- < Эхи > --
 Nп/п : 46 из 100
 От   : Nil A                               2:5015/46         05 мар 26 07:59:18
 К    : Eugene Palenock                                       05 мар 26 08:02:03
 Тема : [PATCH 2/3] Fix: Prevent UUE line corruption by quote/wrap logic
----------------------------------------------------------------------------------
                                                                                 
@MSGID: 2:5015/46 69a90e2d
@REPLY: 2:5020/2065@FidoNet 5e34603c
@CHRS: CP866 2
@TZUTC: 0300
@TID: hpt/lnx 1.9
Hello, Eugene!

Friday January 31 2020 20:13, from Eugene Palenock -> Stas Mishchenkov:

Не прошло и 6ти лет.

 SM>> Пробел в конце второй строчки и перекодированная третья строка.
 SM>> Сам файл, который был заююкан:
 SM>> https://brorabbit.g0x.ru/uue/scorpions_blackout.mp3

 EP> У меня тоже баг. GoldED+/W32-MSVC 1.1.5-b20180707
 EP> Заююкал - разююкал - файл не совпадает с оригиналом...

ПочиНИЛ.

From e521d0b4e9c38a092c10d637ff40cc9264059066 Mon Sep 17 00:00:00 2001
From: Nil Alexandrov <nil.alexandrov@gmail.com>
Date: Wed, 4 Mar 2026 23:53:08 -0500
Subject: [PATCH 2/3] Fix: Prevent UUE line corruption by quote/wrap logic

- Add robust is_uue_line() detection to identify UUE-encoded lines.
 - Update is_quote(), is_quote2(), and setlinetype() to never treat
UUE lines as quotes.
 - Update MakeLineIndex/put_on_new_line() to prevent paragraph joining
of UUE lines.
 - This prevents GoldEd+ from corrupting UUE-encoded data during
editing, import, export, or display.
 - Resolves issue where UUE lines containing `>` or similar quote
patterns were misidentified and joined, causing data loss.
-+-
 golded3/geedit.cpp |  7 ++++-
 golded3/geline.cpp |  4 +++
 golded3/geprot.h   |  1 +
 golded3/geutil.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/golded3/geedit.cpp b/golded3/geedit.cpp
index 0850847..83399c3 100644
--- a/golded3/geedit.cpp
+++ b/golded3/geedit.cpp
@@ -114,7 +114,12 @@ void IEclass::setlinetype(Line* __line)

     __line->type &= ~(GLINE_ALL|GLINE_TEAR|GLINE_ORIG|GLINE_TAGL);

-    if (is_quote(__line->txt.c_str()) &&
 + // Treat UUE Encoded Payload as strict un-wrappable hard lines
unconditionally
+    if (is_uue_line(__line->txt.c_str()))
+    {
+        __line->type |= GLINE_HARD;
+    }
+    else if (is_quote(__line->txt.c_str()) &&
             is_quote2(__line, __line->txt.c_str()))
     {
         __line->type |= GLINE_QUOT;
diff --git a/golded3/geline.cpp b/golded3/geline.cpp
index 762e6bc..8db89d4 100644
--- a/golded3/geline.cpp
+++ b/golded3/geline.cpp
 @@ -2167,6 +2167,10 @@ static bool check_multipart(const char* ptr,
char* boundary)
 inline bool put_on_new_line(const char *ptr)
 {

+    // Never allow UUE encodings to be concatenated behind unwrapped strings
+    if (is_uue_line(ptr))
+        return true;
+
     if((*ptr == CR) or
             (*ptr == CTRL_A) or
             is_quote(ptr) or
diff --git a/golded3/geprot.h b/golded3/geprot.h
index d348e26..7395111 100644
--- a/golded3/geprot.h
+++ b/golded3/geprot.h
 @@ -467,6 +467,7 @@ bool edit_pathname(char* buf, int buf_size, char*
title, int helpcat);
 int   GetAkaNo(const ftn_addr& __aka);
 int   GetQuotestr(const char* ptr, char* qbuf, uint* qlen);
 int   cmp_quotes(char* q1, char* q2);
+bool  is_uue_line(const char* ptr);
 int   is_quote(const char* ptr);
 bool  is_quote2(Line* line, const char* ptr);
 int   IsQuoteChar(const char* s);
diff --git a/golded3/geutil.cpp b/golded3/geutil.cpp
index 466f91d..d429367 100644
--- a/golded3/geutil.cpp
+++ b/golded3/geutil.cpp
@@ -373,6 +373,65 @@ void title_shadow()
     w_shadow();
 }

+//  ------------------------------------------------------------------
+// UUE character decode: maps ASCII to 6-bit value, -1 = invalid.
+static int uu_xlat(unsigned char c)
+{
+    if (c >= ` ` && c < (` ` + 64))     return c - ` `;
+    if (c >= ``` && c < (``` + 32))     return c - ```; // lowercase alias
+    return -1;
+}
+
+// UUE Detection Heuristic
+bool is_uue_line(const char* ptr)
+{
+    if (!ptr || !*ptr) return false;
+
+    const unsigned char* s = (const unsigned char*)ptr;
+    int linelen = 0;
+    while (s[linelen] && s[linelen] != `
` && s[linelen] != `
`) {
+        linelen++;
+    }
+
+    if (linelen == 0) return false;
+
+    int decoded_bytes = uu_xlat(s[0]);
+    if (decoded_bytes < 0 || decoded_bytes > 45) return false;
+
+    // An empty line encoding 0 bytes (e.g. at the end of UUE blocks)
+    if (decoded_bytes == 0) return (linelen <= 2);
+
+    int expected = 1 + ((decoded_bytes + 2) / 3) * 4;
+    int datalen = linelen;
+
+    // Tolerate one trailing checksum character
+    if (datalen == expected + 1) datalen = expected;
+
+    bool length_ok = false;
+    if (datalen == expected) {
+        length_ok = true;
+    } else {
+        int max_expected = 61; // 1 + ceil(45/3)*4
+        if (datalen > expected && datalen <= max_expected) {
+            length_ok = true;
+        } else {
+            // Padding variance handling
+            switch (decoded_bytes % 3) {
+                case 1: if (expected - 2 == datalen) length_ok = true; break;
+                case 2: if (expected - 1 == datalen) length_ok = true; break;
+            }
+        }
+    }
+
+    if (!length_ok) return false;
+
+    // Validate overall data stream
+    for (int i = 0; i < datalen; i++) {
+        if (uu_xlat(s[i]) < 0) return false;
+    }
+
+    return true;
+}

 //  ------------------------------------------------------------------

@@ -395,6 +454,8 @@ int IsQuoteChar(const char* s)

 int is_quote(const char* ptr)
 {
+    // Prevent corrupting UUE Lines
+    if (is_uue_line(ptr)) return false;

     const char* endptr = ptr + 11;

@@ -402,6 +463,9 @@ int is_quote(const char* ptr)
     while((*ptr == ` `) or (*ptr == LF) or issoftcr(*ptr))
         ptr++;

+    // Prevent corrupting UUE Lines with accidental leading whitespace
+    if (is_uue_line(ptr)) return false;
+
     // Check for empty string
     if((*ptr == NUL) or (ptr >= endptr))
         return false;
@@ -453,6 +517,9 @@ int is_quote(const char* ptr)

 bool is_quote2(Line* line, const char* ptr)
 {
+    // Prevent treating UUE lines as quotes
+    if (is_uue_line(ptr)) return false;
+
     if (!CFG->quoteusenewai) return true;

     char *head = (char *)ptr;
--
2.53.0


Best Regards, Nil
--- GoldED+/LNX 1.1.5-b20260305
 * Origin: Gemini can make mistakes, so double-check it (2:5015/46)
SEEN-BY: 46/49 50/109 104/117 221/6 240/1120 301/1
341/66 451/31 452/28 166
SEEN-BY: 455/19 460/58 463/68 4500/1 5000/111
5015/42 46 255 519 5019/40 400
SEEN-BY: 5020/101 113 545 620 715 830 846 848
1042 2992 4441 12000 5022/128
SEEN-BY: 5029/32 5030/49 115 1081 1474 5049/1 3
5050/151 5053/51 58 5054/89
SEEN-BY: 5058/104 5060/900 5061/133 5068/45 5083/1
444 6078/80 6090/1
@PATH: 5015/46 5020/1042 4441



   GoldED+ VK   │                                                 │   09:55:30    
                                                                                
В этой области больше нет сообщений.

Остаться здесь
Перейти к списку сообщений
Перейти к списку эх