Problems with regexes when porting from Ruby to PHP - php

I have two bits of code that seem to be correct translations of one another. They unfortunately appear to return different values.
Code in Ruby:
def separate(text,boundary = nil)
# returns array of strings and arrays containing all of the parts of the email
textList = []
if !boundary #look in the email for "boundary= X"
text.scan(/(?<=boundary=).*/) do |bound|
textList = recursiveSplit(text,bound)
end
end
if boundary
textList = recursiveSplit(text,boundary)
end
puts textList.count
return textList
end
def recursiveSplit(chunk,boundary)
if chunk.is_a? String
searchString = "--" + boundary
ar = chunk.split(searchString)
return ar
elsif chunk.is_a? Array
chunk do |bit|
recursiveSplit(bit,boundary);
end
end
end
Code in PHP:
function separate($text, $boundary="none"){
#returns array of strings and arrays containing all the parts of the email
$textBlock = [];
if ($boundary == "none") {
preg_match_all('/(?<=boundary=).*/', $text, $matches);
$matches = $matches[0];
foreach ($matches as $match) {
$textList = recursiveSplit($text,$match);
}
}else {
$textList = recursiveSplit(text,boundary);
}
var_dump($textList);
return$textList;
}
function recursiveSplit($chunk,$boundary){
if (is_string($chunk)) {
$ar = preg_split("/--".$boundary."/", $chunk);
//$ar = explode($searchString, $chunk);
return $ar;
}
elseif (is_array($chunk)) {
foreach ($chunk as $bit) {
recursiveSplit($bit,$boundary);
}
}
}
var_dump($textList) shows an array of length 3, whereas textList.count => 4. What gives?
Anonymized $text example:
MIME-Version: 1.0
Received: by 10.112.170.40 with HTTP; Fri, 3 May 2013 05:08:21 -0700 (PDT)
Date: Fri, 3 May 2013 08:08:21 -0400
Delivered-To: me#gmail.com
Message-ID: <CADPp44E47syuXvP1K-aemhcU7vdSijZkfKLu-74QPWs9U9551Q#mail.gmail.com>
Subject: MiB 5/3/13 7:43AM (EST)
From: Me <me#gmail.com>
To: Someone <someone#aol.com>
Content-Type: multipart/mixed; boundary=BNDRY1
--BNDRY1
Content-Type: multipart/alternative; boundary=BNDRY2
--BNDRY2
Content-Type: text/plain; charset=ISO-8859-1
-TEXT STUFF HERE. SAYING THINGS
ABOUT CERTAIN THINGS
--BNDRY2
Content-Type: text/html; charset=ISO-8859-1
<div dir="ltr">-changed signature methods to conform more to working clinic header methods(please test/not testable in simulator)<div style>-confirmed that signature image is showing up in simulator. Awaiting further tests</div>
<div style>-Modified findings spacing/buffer. See if you like it</div></div>
--BNDRY2--
--BNDRY1
Content-Type: application/zip; name="Make it Brief.ipa.zip"
Content-Disposition: attachment; filename="Make it Brief.ipa.zip"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_hg9biuno0
<<FILE DATA>>
--BNDRY1--
Run separate(text) on example or any gmail "view original" email in order to reproduce error

BINGO ZINGO Figured it out!
Apparently, in PHP, in order to change a variable inside a loop involving that variable, you have to preface the variable with '&'
Added '&' and fixed some general recursion errors and it ran smoothly.

Related

How to extract certificates from app attestation object using php?

I tried to set up app attestation between my app and php but I rarely find any other source of explaination than Apple's own documentation, which let me stuck quite at an early state. So far I got the following steps:
On the client side, following https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity, I creted my attestation as a base64 encoded string:
attestation.base64EncodedString()
I then send that string to the server, following https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server from now on.
The documentation says, that the attestation is in the CBOR format. I therefor first decode the base64 encoded string and parse it using (https://github.com/Spomky-Labs/cbor-php).
<?php
use CBOR\Decoder;
use CBOR\OtherObject;
use CBOR\Tag;
use CBOR\StringStream;
$otherObjectManager = new OtherObject\OtherObjectManager();
$tagManager = new Tag\TagObjectManager();
$decoder = new Decoder($tagManager, $otherObjectManager);
$data = base64_decode(/* .. base64 encoded attestation string as send from the client (see swift snippet above) */);
$stream = new StringStream($data);
$object = $decoder->decode($stream);
$norm = $object->getNormalizedData();
$fmt = $norm['fmt'];
$x5c = $norm['attStmt']['x5c'];
From the documentation, the normalized object should have the following format:
{
fmt: 'apple-appattest',
attStmt: {
x5c: [
<Buffer 30 82 02 cc ... >,
<Buffer 30 82 02 36 ... >
],
receipt: <Buffer 30 80 06 09 ... >
},
authData: <Buffer 21 c9 9e 00 ... >
}
which it does:
$fmt == "apple-appattest" // true
Then the next according to the documentation is described as:
Verify that the x5c array contains the intermediate and leaf certificates for App Attest, starting from the credential certificate in the first data buffer in the array (credcert). Verify the validity of the certificates using Apple’s App Attest root certificate.
However, I don't know how to proceed further on this. The content of e.g. $norm['attStmt']['x5c'][0] is a mix of readable chars and glyphs. To give you an idea, this is a random substring from the content of $norm['attStmt']['x5c'][0]: "Certification Authority10U Apple Inc.10 UUS0Y0*�H�=*�H�=B��c�}�". That's why I'm not really sure wheather I have to perform any further encodeing/decoding steps.
I tried parsing the certificate but without any luck (both var_dump return false):
$cert = openssl_x509_read($x5c[0]);
var_dump($cert); // false - indicating that reading the cert failed
$parsedCert = openssl_x509_parse($cert, false);
var_dump($parsedCert); // false - of course, since the prior step did not succeed
Any ideas, guidance or alternative ressources are highly appreciated. Thank you!
After a while I came up with the following solution. The $x5c field contains a list of certificates, all in binary form. I wrote the folowing converter to create a ready-to-use certificate in PEM format, which does the following:
base64 encode the binary data
break lines after 64 bytes
add BEGIN and END markers (also note the trailing line-break on the end certificate line)
function makeCert($bindata) {
$beginpem = "-----BEGIN CERTIFICATE-----\n";
$endpem = "-----END CERTIFICATE-----\n";
$pem = $beginpem;
$cbenc = base64_encode($bindata);
for($i = 0; $i < strlen($cbenc); $i++) {
$pem .= $cbenc[$i];
if (($i + 1) % 64 == 0)
$pem .= "\n";
}
$pem .= "\n".$endpem;
return $pem;
}
the following then works:
openssl_x509_read(makeCert($x5c[0]))

Parsing PHP with fopen() encoding issue

I'm having issues parsing a csv file in php, using fopen() taking in API data.
My code works when I use a URL that displays the csv file in the browser as stated in 1) below. But I get random characters outputted from a URL that ends in format=csv as seen in 2) below.
1) Working URL: Returned expected values
https://www.kimonolabs.com/api/csv/duo2mkw2?apikey=yjEl780lSQ8IcVHkItiHzzUZxd1wqSJv
2) Not Working URL: Returns random characters
https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv
Here is my code: - using URL (2) above
<?php
$f_pointer=fopen("https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/ last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv","r");
while(! feof($f_pointer)){
$ar=fgetcsv($f_pointer);
echo $ar[1];
echo "<br>";
}
?>
Output: For URL mentioned in (2) above:
root#MorryServer:/# php testing.php
?IU?Q?JL?.?/Q?R??/)?J-.?))VH?/OM?K-NI?T0?P?*ͩT0204jzԴ?H???X???# D??K
Correct Output: If I use URL Type as stated in (1)
root#MorryServer:/# php testing.php
PHP Notice: Undefined offset: 1 in /testing.php on line 24
jackpot€2,893,210
This is an encoding problem.
The given file contains UTF-8 chars. These are read by the fgetcsv function, which is binary safe. Line Endings are Unix-Format ("\n").
The output on the terminal is scrumbled. Looking at the headers sent, we see:
GET https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv --> 200 OK
Connection: close
Date: Sat, 11 Jul 2015 13:15:24 GMT
Server: nginx/1.6.2
Content-Encoding: gzip
Content-Length: 123
Content-Type: text/csv; charset=UTF-8
Last-Modified: Fri, 10 Jul 2015 11:43:49 GMT
Client-Date: Sat, 11 Jul 2015 13:15:23 GMT
Client-Peer: 107.170.197.156:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
Client-SSL-Cert-Subject: /OU=Domain Control Validated/OU=PositiveSSL/CN=www.parsehub.com
Mind the Content-Encoding: gzip: fgetcsv working on an URL doesn't obviously handle gzip encosing. The scrumbled String is just the gzipped content of the "file".
Look at the gzip lib of PHP to first deflate that before parsing it.
Proof:
srv:~ # lwp-download 'https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv' data
123 bytes received
srv:~ # file data
data: gzip compressed data, was "tcW80-EcI6Oj2TYPXI-47XwK.csv", from Unix, last modified: Fri Jul 10 11:43:48 2015, max compression
srv:~ # gzip -d < data
"title","jackpot"
"Lotto Results for Wednesday 08 July 2015","€2,893,210"
To get the proper output, minimal changes are need: Just add a stream wrapper:
<?php
$f_pointer=fopen("compress.zlib://https://www.parsehub.com/api/v2/projects/tM9MwgKrh0c4b81WDT_4FkaC/last_ready_run/data?api_key=tD3djFMGmyWmDUdcgmBVFCd3&format=csv","r");
if ( $f_pointer === false )
die ("invalid URL");
$ar = array();
while(! feof($f_pointer)){
$ar[]=fgetcsv($f_pointer);
}
print_r($ar);
?>
Outputs:
Array
(
[0] => Array
(
[0] => title
[1] => jackpot
)
[1] => Array
(
[0] => Lotto Results for Wednesday 08 July 2015
[1] => €2,893,210
)
)

How to remove original email message in reply message using php?

I am using PHP to get the email from the POP3 server. However, some emails also contain the original message which I sent to them.
How do I remove the original message, so the PHP script will only get the reply message?
For example:
Email sent from A to B
A
11:08 PM (1 minute ago)
to B
how are you?
Email replied from B to A
11:08 PM (0 minutes ago)
to A
I am fine
> On Sun, Mar 8, 2015 at 11:08 PM, Ryan Ho <ryan#incube.com.hk> wrote:
> how are you?
I would like to remove those wordings "On Sun Mar 8,.... to how are you?".
Thanks.
First, you can save the email in a file, then you can remove all the lines starting with > using a regular expression.
This is because all lines from the original message start with the symbol >, including the text:
On Sun, Mar 8, ... wrote: how are you?
Here is the code doing that:
<?php
$filename="email-full.txt";
$outfile="email-noreply.txt";
$string = file_get_contents($filename);
$array = explode("\n",$string);
foreach($array as $arr) {
if(!(preg_match("/^>/",$arr))) {
$output[] = $arr;
}
}
$out = implode("\n",$output);
file_put_contents($outfile,$out);
?>

Parse Mailgun headers

I have the following JSON from a Mailgun webhook (Delivered) that I need to extract the subject line from.
They do not appear to be following a typical key value JSON format, short of a bunch of foreach loops is there a way to extract this data?
[["Received", "by luna.mailgun.net with SMTP mgrt 8734663311733; Fri, 03 May 2013 18:26:27 +0000"], ["Content-Type", ["multipart/alternative", {"boundary": "eb663d73ae0a4d6c9153cc0aec8b7520"}]], ["Mime-Version", "1.0"], ["Subject", "Test deliver webhook"], ["From", "Bob <bob#fvrs.org>"], ["To", "Alice <alice#example.com>"], ["Message-Id", "<20130503182626.18666.16540#fvrs.org>"], ["X-Mailgun-Variables", "{\"my_var_1\": \"Mailgun Variable #1\", \"my-var-2\": \"awesome\"}"], ["Date", "Fri, 03 May 2013 18:26:27 +0000"], ["Sender", "bob#fvrs.org"]]
The reason why it's not a dictionary is because in emails you can have the same header appear more than once.
You just a single loop, though:
$subject = null;
foreach ($data as $header) {
if ($header[0] == 'Subject') {
$subject = $header[1];
break;
}
}

MYSQL Error while inserting header value in DB

I am trying to insert header value of an email into DB but I am getting below mentioned error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'color:#1F497D'> =
while variable which holds this value is :
$headerValue="x-store-info: J++/JTCzmObr++wNraA4Pa4f5Xd6uensVd8mvt5QRSOLhsGzuy+tUtmSAtwbT+Lhg32fI7JkT4T+oCCjUH2Po9WkZAzmMIYU0MxTJOx1JRLfrWSAJ4yq+QDUHkUMkOR6HLEpJj1jCGc=
Authentication-Results: hotmail.com; spf=neutral (sender IP is 66.39.4.58) smtp.mailfrom=xyz.abh#abc.in; dkim=none header.d=abc.in; x-hmca=none header.id=xyz.abh#abc.in
X-SID-PRA: xyz.abh#abc.in
X-AUTH-Result: NONE
X-SID-Result: NONE
X-Message-Status: n:n
X-Message-Delivery: Vj0xLjE7dXM9MDtsPTE7YT0xO0Q9MTtHRD0xO1NDTD0x
X-Message-Info: NhFq/7gR1vQP6lZqH93tpVQFT69R+Bmv3UykwdELmYZ7B3Xiq5XoKqM5Sg6LjXxhKff4sob+93uheSiXVqp/rY0haPrEn6zvVhDahXaFE0nw9nQNG7DoZ7tXJdlzLLUsiyHtmFWhLupgJOiCWx/N3LIzuBcoyXRyO+0UqhjFaJY+pNdDEFGjgVOsdbFgKDHkJCilkjEyMXrCtfvi6LQwqpvJ18a+yny6
Received: from mail1.g9.pair.com ([66.39.4.58]) by BAY0-MC2-F25.Bay0.hotmail.com with Microsoft SMTPSVC(6.0.3790.4900);Sun, 9 Mar 2014 10:21:21 -0700
Received: from abccto (unknown [182.71.149.242])by mail1.g9.pair.com (Postfix) with ESMTPSA id 447B739863for <outloo1#outlook.com>; Sun, 9 Mar 2014 13:21:18 -0400 (EDT)
From: "xyz t" <xyz.dps#abc.in>
To: <outloo1#outlook.com>
Subject: This is test 1
Date: Sun, 9 Mar 2014 22:51:15 +0530
Message-ID: <001701cf3bbb$fc5a1940$f50e4bc0$#abc.in>
MIME-Version: 1.0
Content-Type: multipart/alternative;boundary="----=_NextPart_000_0018_01CF3BEA.16125540"
X-Mailer: Microsoft Office Outlook 12.0
Thread-Index: Ac87u+X0jencwqnORxOvsW8e4oF0PQAAAYbQ
Content-Language: en-us
Return-Path: xyzt#abc.in
X-OriginalArrivalTime: 09 Mar 2014 17:21:21.0782 (UTC) FILETIME=[FDAB5160:01CF3BBB]
This is a multi-part message in MIME format.
------=_NextPart_000_0018_01CF3BEA.16125540
Content-Type: text/plain;charset="us-ascii"
Content-Transfer-Encoding: 7bit
Hi Freind
------=_NextPart_000_0018_01CF3BEA.16125540
Content-Type: text/html;charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" =
xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" =
xmlns=3D"http://www.w3.org/TR/REC-html40"><head><META =
HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Dus-ascii"><meta name=3DGenerator content=3D"Microsoft Word 12 =
(filtered medium)"><style><!--
/* Font Definitions */
#font-face{font-family:"Cambria Math";panose-1:2 4 5 3 5 4 6 3 2 4;}
#font-face{font-family:Calibri;panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal{margin:0in;margin-bottom:.0001pt;font-size:11.0pt;font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink{mso-style-priority:99;color:blue;text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed{mso-style-priority:99;color:purple;text-decoration:underline;}
span.EmailStyle17{mso-style-type:personal;font-family:"Calibri","sans-serif";color:windowtext;}
span.EmailStyle18{mso-style-type:personal-reply;font-family:"Calibri","sans-serif";color:#1F497D;}
.MsoChpDefault{mso-style-type:export-only;font-size:10.0pt;}
#page WordSection1{size:8.5in 11.0in;margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]--></head><body lang=3DEN-US link=3Dblue =
vlink=3Dpurple><div class=3DWordSection1><p =
class=3DMsoNormal><o:p> </o:p></p><p class=3DMsoNormal>Hi =
xyz<span style=3D'color:#1F497D'> =
</span><o:p></o:p></p></div></body></html>
------=_NextPart_000_0018_01CF3BEA.16125540--"
I had obtained this value by applying :
$header = preg_replace('~[\r\n]+[ \t]+~', null, $obj_thang);
$header = preg_replace('~[ \t]+~', ' ', $header);
1. string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier = NULL ] )
2. Escapes special characters in the unescaped_string, taking into
account the current character set of the connection so that it is
safe to place it in a mysql_query(). If binary data is to be
inserted, this function must be used.
3. mysql_real_escape_string() calls MySQL's library function
mysql_real_escape_string, which prepends backslashes to the
following characters: \x00, \n, \r, \, ', " and \x1a.
4. This function must always (with few exceptions) be used to make data
safe before sending a query to MySQL.
Further details are at -:
http://in3.php.net/mysql_real_escape_string

Categories