Jak zdekodować base64url?

0

Witam,

Piszę sobie programik odczytujący maila z gmaila, odczytuje on maile i wrzuca do plika javascritpt.
W JS mam tablicę obiektów z parametrami i w niektórych treściach są same liczby - dowiedziałem się, że to base64.
Potem chcę to wrzucić do html.
Kiedy dekompiluje to w dekoderze online tekst wygląda jak normalny html.
Kiedy atob()uje w pliku html to dostaje info że łańcuch jest niepoprawnie zakodowany.

<script src="EBSetupEx.js"></script>
<script src="EBScrollableElementList.js"></script>
<script src="mail.js"></script>
<script defer>
	class myApp {
		constructor() {
			ElementBuilder.setWorkplace();
	//lewe okno		
   this.left_window = ElementBuilder.createElement("DIV", "display:flex;overflow:auto; flex-direction:column; justify-content:flex-start; padding:0%; margin:0%; height:99.6%; width:25%; padding:0%; border:1px solid white; background: linear-gradient(to right, #440000, #AA0000); color:white; font:italic bold 16px arial,serif;", "left_window_class", this, document.body, false).element;

   //prawe okno (ramka)
   this.right_window = ElementBuilder.createElement("IFRAME", "display:flex;overflow:auto; flex-direction:column; padding:0%; margin:0%; height:99.6%; width:75%; padding:0%; border:1px solid white; background: linear-gradient(to right, #440000, #AA0000); color:white; font:italic bold 16px arial,serif;", "right_window_class", this, document.body, false).element;

//wczytuje 7 maili
			for (let i = 0; i < 7; i++) {//tworzy obiekty z nazwami maili i podpina zdarzenie ładujące zawartosc
				var z = ElementBuilder.createElement("DIV", "display:flex;cursor:pointer;flex-direction:column; justify-content:flex-start; padding:0%; margin:0%; height:30%; width:99%; padding:0%; border:1px solid white; background: linear-gradient(to right, #440000, #AA0000); color:white; font:italic bold 16px arial,serif;", "left_choice_class", this, this.left_window, false).setInnerHTML(emailsData[i].from.replaceAll('<', '&lt;').replaceAll('>', '&gt;')).element;
				z.index = i;
				z.setAttribute("z", i); 
				z.setAttribute(`onClick`, `my_new_shining_app.run(this.attributes.getNamedItem("z").value);`);
				this.left_window.appendChild(z);
			}
//funkcja dekodująca maila i wrzucająca do ramki
			this.run = function(nr) {
									var decodedContent = atob(emailsData[nr].body);
      									my_new_shining_app.right_window.contentWindow.document.write(decodedContent);
      									my_new_shining_app.right_window.contentWindow.document.close();}
     
		
	}}
  setTimeout(function() {my_new_shining_app = new myApp();}, 300);
</script>

Jak żyć?

0

Podałeś za mało kodu, żeby można było odtworzyć u siebie.

0

@overcq: masz http://infinityhost.ct8.pl/mail.js

window.top.r[0]  w javascript ma zawartość  tego kodu.
window.top.r=["PCFk...."];

kodery online dekodują normalny html
Dostaje info

cannot run it on window, string was incorrectly encoded
2

Masz po prostu dziwne znaki w tym base64. Patrząc na listę wariantów widać, że to jest odmiana base64url.

Można zrobić prostą konwersję:

atob(a.replaceAll('-', '+').replaceAll('_', '/'))

0

Użyłem php i przekonwertował bez problemu (tylko chyba zablokowało korzystanie z plików zewnętrznych, bo na localhoscie to odpaliłem - więc treść była ale inna niż orginalnie). Teraz pythonem spróbuję to samo.

0
johnny_Be_good napisał(a):

Użyłem php i przekonwertował bez problemu (tylko chyba zablokowało korzystanie z plików zewnętrznych, bo na localhoscie to odpaliłem - więc treść była ale inna niż orginalnie). Teraz pythonem spróbuję to samo.

PHP niepoprawnie zamienia base64, nie traktuj tego jako dobry wyznacznik. Posłuchaj rady @szatkus1

0

Jeżeli PHP jakoś dekoduje i faktycznie uzyskuje się oryginalną treść, to potem można otrzymaną treść zakodować (za pomocą JS lub PHP) i porównać. Nie chodzi tylko o "entery", ale może są jakieś różnice i da się dopatrzeć prawidłowości, która pozwala wymyśleć algorytm przygotowania ciągu BASE64 pod funkcje btoa().

0

wrzuć nam całą treść z emailsData[nr].body, my nie wiemy co tam jest, ale jest tam coś nietypowego, atob widzę radzi sobie z dodatkowymi białymi znakami bez problemu

0

Ok, siadłem do obiadu z tym Twoim cudem i sprawa wygląda tak:

  • w zakodowanym stringu są dwa dodatkowe znaki:
    • - ("pauza") - która oznacza ZDEKODOWANY JUŻ znak ">"
    • _ ("podkreślenie", "podłoga"), która oznacza ZDEKODOWANY JUŻ znak " "

W takim przypadku najlepiej więc rozbić string na kawałki wg tych dwóch znaków, dekodować pozostałe fragmenty i łączyć je tym, jak wskazano.

Więc zakładając, że r zawiera już ten ciąg base64 to w ten sposób uzyskasz wynik:

const result = r.split("-").flatMap(s => {
    return s.split("_").map(v => {
        return atob(v);
    }).join(" ");
}).join(">");

Przykładowy wynik dla tego co masz w mail.js:

<!doctype html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <meta name="format-detection" content="telephone=no">
            <meta name="format-detection" content="address=no">
            <meta name="x-apple-disable-message-reformatting">
            <link href="https://fonts.googleapis.com/css family=Lato:400,700,900" rel="stylesheet" type="text/css">
            <!--[if mso]>
            <style type="text/css">
            body, table, td {font-family: Arial, Helvetica, sans-serif !important;}
            </style>
            <![endif]-->
            <style>
                body {
                  margin: 0;
                }
                .css-uegzbq{font-family:Lato,Arial,Helvetica,sans-serif;margin:0;padding:0;font-size:18px;font-weight:normal;font-stretch:normal;font-style:normal;line-height:28px;-webkit-letter-spacing:normal;-moz-letter-spacing:normal;-ms-letter-spacing:normal;letter-spacing:normal;color:#505863;}.css-uegzbq,.css-uegzbq *{font-family:Lato,Arial,Helvetica,sans-serif;}.css-1kbqv69{width:100%;background-color:#f5f6f7;text-align:center;}.css-l1mraf{max-width:500px;width:500px;margin:0 auto;background-color:#fff;text-align:left;}.css-1iuszfz{padding-top:35px;border-top:1px solid transparent;border-left:1px solid transparent;border-right:1px solid transparent;padding-left:24px;padding-right:24px;padding-bottom:30px;width:100%;}.css-9th5vf{color:#1861bf;}a.cleanBoldLink{font-family:Arial,Helvetica,sans-serif !important;font-weight:bold;-webkit-text-decoration:none;text-decoration:none;color:#1861bf;}a.clearLink{color:#1861bf;-webkit-text-decoration:none;text-decoration:none;}.css-nt1wjc{padding-left:24px;padding-right:24px;padding-top:0px;padding-bottom:0px;border-left:1px solid transparent;border-right:1px solid transparent;}.buttonCenterprimarydefault{font-family:Arial,Helvetica,sans-serif !important;font-weight:bold;font-size:15px;color:#fff !important;}.buttonCentersecondarydefault{font-family:Arial,Helvetica,sans-serif !important;font-weight:bold;font-size:15px;color:#1861bf !important;}.css-1of8vp0{border-bottom:1px solid transparent;border-left:1px solid transparent;border-right:1px solid transparent;}img.fishbowlLogoSmall{width:63px;vertical-align:text-top;}.css-96uds2{color:#1861bf;-webkit-text-decoration:none;text-decoration:none;}.css-ba2w2p{width:30px;height:30px;vertical-align:middle;border-radius:30px;}.css-1ic066d{padding-left:20px;}.css-ip60z3{height:0px;border:none;margin:0;padding:0;width:100%;border-top:1px solid #dee0e3;}.css-u6cj4z{padding-left:24px;padding-right:24px;padding-top:0px;padding-bottom:4px;border-left:1px solid transparent;border-right:1px solid transparent;}.css-x3v1q8{font-size:24px;font-weight:900;font-family:'Lato';line-height:36px;-webkit-letter-spacing:0em;-moz-letter-spacing:0em;-ms-letter-spacing:0em;letter-spacing:0em;text-align:center;color:#20262e;}.css-3arti4{font-size:18px;font-weight:700;font-family:'Lato';line-height:28px;-webkit-letter-spacing:0em;-moz-letter-spacing:0em;-ms-letter-spacing:0em;letter-spacing:0em;text-align:left;color:#20262e;}.css-ql0l4d{padding-left:24px;padding-right:24px;padding-top:0px;padding-bottom:14px;border-left:1px solid transparent;border-right:1px solid transparent;}.css-16hggsa{font-size:15px;font-weight:400;font-family:'Lato';line-height:24px;-webkit-letter-spacing:0em;-moz-letter-spacing:0em;-ms-letter-spacing:0em;letter-spacing:0em;text-align:left;color:#20262e;}.css-l72z7c{padding-left:24px;padding-right:24px;padding-top:24px;padding-bottom:20px;border-left:1px solid transparent;border-right:1px solid transparent;}.css-1stwpoo{box-sizing:border-box;border-radius:3px;padding-left:16px;padding-right:16px;}.css-1gxp3tr{width:30px;max-width:30px;padding-right:8px;}.css-glxy0g{vertical-align:middle;font-size:12px;line-height:15px;color:#505863;text-align:left;font-weight:700;}.css-2dxww1{font-size:12px;line-height:20px;text-align:right;color:#505863;min-width:140px;}.css-du5m07{padding-top:8px;padding-bottom:12px;font-size:15px;line-height:20px;color:#505863;}.css-d914bh{font-weight:bold;color:#1861bf;display:inline-block;}.css-rvlokx{padding-left:8px;font-size:12px;line-height:20px;color:#505863;}.css-1f225tk{padding-left:24px;padding-right:24px;padding-top:28px;padding-bottom:32px;border-left:1px solid transparent;border-right:1px solid transparent;}.buttonCenterprimarymarketing{font-family:Arial,Helvetica,sans-serif !important;font-weight:bold;font-size:18px;color:#fff !important;}.css-w9sma4{border:1px solid transparent;border-radius:3px;border-color:transparent;font-weight:bold;font-size:15px;color:#fff !important;cursor:pointer;display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;-webkit-transition:color 0.2s ease-out,background-color 0.2s ease-out,border-color 0.2s ease-out;transition:color 0.2s ease-out,background-color 0.2s ease-out,border-color 0.2s ease-out;font-family:Lato,Arial,Helvetica,sans-serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:88px;-webkit-text-decoration:none;text-decoration:none;line-height:24px;border-style:solid;width:327px;text-align:center;mso-hide:all;color:#fff !important;background-color:#1861bf;padding:9px 16px;font-size:18px;line-height:28px;}.css-w9sma4:focus{outline:0;}.css-w9sma4:link,.css-w9sma4:visited{color:#fff;}@media not all and (pointer:coarse){.css-w9sma4:hover{background-color:#0c4085;border-color:#0c4085;color:#fff !important;}}.css-w9sma4[disabled]{background-color:#abccf7;cursor:not-allowed;}.css-1l7m9ce{padding:16px 24px;font-size:12px;background:none;}.css-1l7m9ce a.footerLink{color:#1861bf;-webkit-text-decoration:underline;text-decoration:underline;white-space:nowrap;}.css-13kj92h{color:#7F7F7F;line-height:20px;margin:0;margin-top:0;margin-bottom:0;text-align:center;}a.css-1s2ng7x{color:#1861bf;-webkit-text-decoration:underline;text-decoration:underline;white-space:nowrap;}.buttonCenterspecialdefault{font-family:Arial,Helvetica,sans-serif !important;font-weight:bold;font-size:15px;color:#fff !important;}a.cleanBoldLink{font-family:Glassdoor Sans,SF Pro,Segoe UI,Roboto,Arial,Helvetica,sans-serif;font-weight:bold;-webkit-text-decoration:none;text-decoration:none;color:#1861bf;}.buttonCenterspeciallg{font-family:Arial,Helvetica,sans-serif !important;font-weight:600;font-size:14px;color:#000000 !important;white-space:nowrap;}.buttonCentersecondarysm{font-family:Arial,Helvetica,sans-serif !important;font-weight:600;font-size:14px;color:#000000 !important;white-space:nowrap;}
            </style>
        </head>
        <body id="GDEmail">
            <div id="GDEmailWrapper" class="css-uegzbq e2c2s610"><table cellSpacing="0" cellPadding="0" color="#f5f6f7" class="css-1kbqv69 e2c2s614"><tr><td><table cellSpacing="0" cellPadding="0" class="css-l1mraf e2c2s613"><tr><td colSpan="3" style="text-align:center" class="css-1iuszfz e2c2s611"><a class="css-9th5vf ep11te10" href="https://www.glassdoor.com" target="_blank" universal="true"><img src="https://www.glassdoor.com/crs/mail/logos/glassdoor_tng_logo_green.png" alt="Glassdoor" title="Glassdoor" height="30" width="143"/></a></td></tr><tr><td colSpan="3" class="css-u6cj4z ep11te12"><h1 class="css-x3v1q8 e56kp3r0">Tech Digest</h1></td></tr><tr><td colSpan="3" class="css-nt1wjc ep11te12"><span class="css-3arti4 e56kp3r1">Hey wojciech!</span></td></tr><tr><td colSpan="3" class="css-ql0l4d ep11te12"><span class="css-16hggsa e56kp3r2">In case you missed it, here&#x27;s what folks are talking about in your industry bowl.</span></td></tr><tr><td colSpan="3" class="css-l72z7c ep11te12"><a class="css-96uds2 ep11te10" href="https://www.glassdoor.com/Community/bowl-B55375ce690f5eebe1d2a0f88/post-P64bb65141f7dc5c308ecb90f.htm?uvk=yOrcnrn%3ARLwWTPT1NIz89oRKEmxow&amp;utm_medium=email&amp;utm_source=industryDigest&amp;utm_campaign=industryDigest&amp;utm_content=industryDigest" target="_blank" universal="true"><table cellSpacing="0" cellPadding="0" border="0" width="100%" class="css-1stwpoo e1p9qaam0" style="padding:0px"><tr><td class="css-1stwpoo e1p9qaam0" style="margin:0px"><table border="0" cellPadding="0" cellSpacing="0" width="100%"><tr><td class="css-1gxp3tr e1p9qaam2"><img src="http://www.glassdoor.com/crs/mail/icons/building-75x75.png" width="30" class="css-ba2w2p e1p9qaam1"/></td><td width="100%" class="css-glxy0g e1p9qaam3"><span class="css-9th5vf e1p9qaam4">Tech</span><br/>Software Engineer</td><td class="css-2dxww1 e1p9qaam5">7/22/23</td></tr><tr><td colSpan="3" class="css-du5m07 e1p9qaam6">How to tell my manager that my team hates working with this one particular no code tool that we have invested so much money, effort, and time in. I...<!-- --> <span class="css-d914bh e1p9qaam10">read more</span></td></tr><tr><td colSpan="3"><table border="0" cellPadding="0" cellSpacing="0"><tr><td><img src="https://www.glassdoor.com/crs/mail/icons/fishbowl_reactions.png" alt="[Reaction]" height="16"/></td><td class="css-rvlokx e1p9qaam7">8</td><td class="css-1ic066d e1p9qaam8"><img src="https://www.glassdoor.com/crs/mail/icons/fishbowl_bubble.png" width="16" alt="[Comment Bubble]"/></td><td class="css-rvlokx e1p9qaam9">10 Comments</td><td></td></tr></table></td></tr></table></td></tr></table></a></td></tr><tr><td colSpan="3" class="css-nt1wjc ep11te12"><table cellSpacing="0" cellPadding="0" border="0" width="100%" class="css-ip60z3 ep11te14" style="padding:0px"><tr><td class="css-ip60z3 ep11te14" style="margin:0px"></td></tr></table></td></tr><tr><td colSpan="3" class="css-l72z7c ep11te12"><a class="css-96uds2 ep11te10" href="https://www.glassdoor.com/Community/bowl-B55375ce690f5eebe1d2a0f88/post-P64bbb7408382ac0f09f5b490.htm?uvk=yOrcnrn%3ARLwWTPT1NIz89oRKEmxow&amp;utm_medium=email&amp;utm_source=industryDigest&amp;utm_campaign=industryDigest&amp;utm_content=industryDigest" target="_blank" universal="true"><table cellSpacing="0" cellPadding="0" border="0" width="100%" class="css-1stwpoo e1p9qaam0" style="padding:0px"><tr><td class="css-1stwpoo e1p9qaam0" style="margin:0px"><table border="0" cellPadding="0" cellSpacing="0" width="100%"><tr><td class="css-1gxp3tr e1p9qaam2"><img src="http://www.glassdoor.com/crs/mail/icons/building-75x75.png" width="30" class="css-ba2w2p e1p9qaam1"/></td><td width="100%" class="css-glxy0g e1p9qaam3"><span class="css-9th5vf e1p9qaam4">Tech</span><br/>Industrial Designer</td><td class="css-2dxww1 e1p9qaam5">7/22/23</td></tr><tr><td colSpan="3" class="css-du5m07 e1p9qaam6">I was recently hired by a startup that promised a bunch of stuff but didnâ
0
dzek69 napisał(a):

Ok, siadłem do obiadu z tym Twoim cudem i sprawa wygląda tak:

  • w zakodowanym stringu są dwa dodatkowe znaki:
    • - ("pauza") - która oznacza ZDEKODOWANY JUŻ znak ">"
    • _ ..>building-75x75.png</td>Tech
      Industrial Designer</td>7/22/23</td></tr><td colSpan="3" class="css-du5m07 e1p9qaam6">I was recently hired by a startup that promised a bunch of stuff but didnâ

Czemu tam się pojawiły te znaki ? a) działanie celowe?, b) amatorka jak we wszystkich firmach? Sam sobie tego nie wysłałem.

0

Nie wiem. Nigdy nie pokazałeś jak pobierasz te maile z gmaila.

0
dzek69 napisał(a):

Nie wiem. Nigdy nie pokazałeś jak pobierasz te maile z gmaila.

from __future__ import print_function
import os.path
import time
import os
import ctypes
import base64

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

# Load the DLL
dll_path = os.path.abspath('hello.dll')
hello_dll = ctypes.CDLL(dll_path)

# Define the function prototype for hello
hello_dll.hello.restype = ctypes.c_int  # Return value is an integer
hello_dll.hello.argtypes = [ctypes.c_char_p, ctypes.c_char_p]  # Arguments are char pointers
hello_dll.show.restype = None  # No return value
hello_dll.show.argtypes = []

def write_to_file(file_path, content):
    try:
        with open(file_path, 'w') as file:
            content = content.replace("<body","<body style='background-color:lightGrey;color:black;font:22px italic arial,serif;'");
            file.write(content)
        print(f"Content written to '{file_path}' successfully.")
    except IOError as e:
        print(f"Error writing to file: {e}")

def fetch_latest_email():
    try:
        # Call the Gmail API
        service = build('gmail', 'v1', credentials=creds)
        results = service.users().messages().list(userId='me', maxResults=1).execute()
        messages = results.get('messages', [])

        if not messages:
            print('No messages found.')
            return

        latest_message_id = messages[0]['id']
        msg = service.users().messages().get(userId='me', id=latest_message_id).execute()
        headers = msg['payload']['headers']

        # Check if the required headers are present in the payload
        email_subject = next((header['value'] for header in headers if header['name'] == 'Subject'), None)
        email_from = next((header['value'] for header in headers if header['name'] == 'From'), None)
        email_date = next((header['value'] for header in headers if header['name'] == 'Date'), None)

        if not email_subject or not email_from or not email_date:
            print('Email headers not found.')
            return

        # Remove the < > characters from email_from
        email_from = email_from.replace('<', '&lt;').replace('>', '&gt;').replace('\\n', '')
        email_date = email_date.replace('<', '').replace('>', '').replace(' ', '').replace('+', '').replace(',', '').replace(':', '').replace('\\', '')


        # Access the email's HTML body
        email_body = ''
        for part in msg['payload']['parts']:
            if 'data' in part['body']:
                # If the body contains data, decode and add it to the email_body variable
                email_body += base64.urlsafe_b64decode(part['body']['data']).decode('utf-8')

        tk = hello_dll.hello(email_from.encode(), email_date.encode())
        if tk == 0:
            print("No need")
        else:
            write_to_file(email_date+'.html', email_body)
            print(email_from)
    except HttpError as error:
        # TODO(developer) - Handle errors from Gmail API.
        print(f'An error occurred: {error}')

if __name__ == '__main__':
    while True:
        creds = None
        # The file token.json stores the user's access and refresh tokens, and is
        # created automatically when the authorization flow completes for the first
        # time.
        if os.path.exists('token.json'):
            creds = Credentials.from_authorized_user_file('token.json', SCOPES)
        # If there are no (valid) credentials available, let the user log in.
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
                creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open('token.json', 'w') as token:
                token.write(creds.to_json())

        fetch_latest_email()
        time.sleep(15)  # Sleep for 2 minutes (120 seconds)

Hello dll to tylko moduł w C do utworzenia bazy danych która przechowuje maile i sprawdza czy nowy jest już w niej czy nie.

0

Ale masz

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STRINGS 200
#define MAX_LENGTH 200

struct mail {
    char from[50];
    char date[50];
};

int length = 0;
struct mail *database = NULL;


void show() {
   
FILE *sourceFile1,*sourceFile2,*sourceFile3, *destFile;
    char ch;

    // Open the source file in read mode
    sourceFile1 = fopen("part_1.dat", "r");
    sourceFile2 = fopen("part_2.dat", "r");
    sourceFile3 = fopen("part_3.dat", "r");
    destFile = fopen("file.html", "w");

while ((ch = fgetc(sourceFile1)) != EOF) {
        fputc(ch, destFile);
    }

fclose(destFile);
destFile = fopen("file.html", "a");
for (int u = 0; u < length; u++) {


printf("%s",database[u].from);
if(u!=length-1){
fprintf(destFile,"%c%s%c%s",34,database[u].from,34,",");}else{
fprintf(destFile,"%c%s%c",34,database[u].from,34);}

}
fclose(destFile);
destFile = fopen("file.html", "a");
while ((ch = fgetc(sourceFile2)) != EOF) {
        fputc(ch, destFile);
    }
fclose(destFile);
destFile = fopen("file.html", "a");
for (int u = 0; u < length; u++) {
printf("Exited file - %s",database[length].date);

char nam[50];
strcpy(nam,database[u].date);
strcat(nam,".html");
if(u!=length-1){

fprintf(destFile,"%c%s%c%s",34,nam,34,",");}else{
fprintf(destFile,"%c%s%c",34,nam,34);}}


fclose(destFile);
destFile = fopen("file.html", "a");
while ((ch = fgetc(sourceFile3)) != EOF) {
        fputc(ch, destFile);
    }
fclose(destFile);
fclose(sourceFile1);
fclose(sourceFile2);
fclose(sourceFile3);

}

int hello(const char *from, const char *date) {
    int test = 0;

    if (length == 0) {
        // Allocate memory for the first entry
        database = (struct mail *)malloc(sizeof(struct mail));
        if (database == NULL) {
            printf("Memory allocation failed.\n");
            return -1; // Return -1 to indicate failure
        }

        // Allocate memory for 'from' and 'date' fields
        //database->from = (char *)malloc(strlen(from) + 1);
        //database->date = (char *)malloc(strlen(date) + 1);

        // Copy 'from' and 'date' values
        strcpy(database[0].from, from);
        strcpy(database[0].date, date);
         printf("added  - %s%s\n",database[0].from,database[0].date); 
        length++;show();
        return 1; // Return 1 to indicate a new entry is added
    } else {
        // Check if the 'from' value already exists
        struct mail *tmp = &database[0];
        for (int u = 0; u < length; u++) {
           // printf("checking  - %s%s\n",from,tmp->from);
            if (strcmp(from, tmp->from) == 0 && strcmp(date, tmp->date) == 0) {
                return 0;
                break;
            }
            tmp++;
        }

        if (test == 0) {
            // If 'from' value doesn't exist, reallocate memory for the new entry
            struct mail *temp = (struct mail *)realloc(database, (length + 1) * sizeof(struct mail));
            if (temp == NULL) {
                printf("Memory reallocation failed.\n");
                return -1; // Return -1 to indicate failure
            }

            // Update 'database' to the new memory block
            database = temp;

            // Allocate memory for 'from' and 'date' fields for the new entry
           // database[length].from = (char *)malloc(strlen(from) + 1);
           // database[length].date = (char *)malloc(strlen(date) + 1);
        strcpy(database[length].from, from);
        strcpy(database[length].date, date);

            // Copy 'from' and 'date' values for the new entry
          //  strcpy(database[length].from, from);
          //  strcpy(database[length].date, date);
            printf("added  - %s%s\n",database[length].from,database[length].date);
            length++;show();return 1;
        }
        return test; // Return 0 if 'from' already existed, 1 if it was added as a new entry
    }
}
0

No to niestety nie wiem skąd te znaki. Ale masz sposób na ich rozwiązanie.

Być może coś jest nie tak jeszcze - w moim poście przykładowy zdekodowany HTML kończy się na I was recently hired by a startup that promised a bunch of stuff but didnâ (tutaj Coyote ucięło post na nieprawidłowych znakach unicode zdaje się) - albo w samym e-mailu coś jest nie tak (jak wyświetla się ten mail w kliencie Gmail?) albo masz jakąś literkę ekstra w pliku mail.js (generalnie błąd tym stringu base64 spowodowany czynnikiem ludzkim) albo czegoś nie dostrzegłem walcząc z problemem i popełniłem jeszcze jakiś błąd. Widać, że problem jest na apostrofie, więc dość specyficznym znaku

Ale może sobie poradzisz już

0

Dzięki, php'em to rozkodowałem tak jak wcześniej pisałem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1