+2015-06-07 Achim Gratz <Stromeko@NexGo.DE>
+
+ * ini.h: Add macros for use within the implementation of the
+ checksum parsers. Hexdigest requires a 2-to-1 and Base64 a 4-to-3
+ conversion. Base64 uses the filename and URL safe alphabet from
+ RFC4648. It would be trivial to additionally process the normal
+ Base64 alphabet but we don't want to allow that in order to be
+ able to use the checksums as filenames without further conversion.
+ (hexnibble, b64url): Process single input character to input value.
+ (nibbled1): Convert 2 processed input values into 1 output value.
+ (b64d1, b64d2, b64d3): Convert 4 input values into 3 output
+ values.
+ * iniparse.yy: Add SHA512B64URL checksum in addition to MD5 and
+ SHA512. Keep symmetry with MD5LINE and also define SHA512LINE
+ syntax.
+ * inilex.ll: Implement existing MD5 and SHA512 checksum parsers
+ using new macros. Implement new SHA512B64URL parser using new
+ macros. Enforce Base64 alphabet as defined in RFC4648 with no
+ padding to enable direct use of checksum values as filenames.
+ Implement SHA512LINE parser.
+
2015-03-25 Corinna Vinschen <corinna@vinschen.de>
* install.cc (sha512_one): Raise buffer size to 64K for performance
extern std::string yyerror_messages; /* textual parse error messages */
extern int yyerror_count; /* number of parse errors */
+/* The following definitions are used in the parser implementation */
+
+#define hexnibble(val) (255 & (val > '9') ? val - 'a' + 10 : val - '0');
+#define nibbled1(v1,v2) (255 & ((v1 << 4) & v2));
+#define b64url(val) \
+ (63 & (( val == '_') ? 63 \
+ : (val == '-') ? 62 \
+ : (val >= 'a') ? val - 'a' + 26 \
+ : (val >= 'A') ? val - 'A' + 0 \
+ : val - '0' + 52))
+#define b64d1(v1,v2,v3,v4) (255 & ((v1 << 2) | (v2 >> 4)));
+#define b64d2(v1,v2,v3,v4) (255 & ((v2 << 4) | (v3 >> 2)));
+#define b64d3(v1,v2,v3,v4) (255 & ((v3 << 6) | v4));
+
#endif /* SETUP_INI_H */
%%
-[0123456789abcdef]{32,32} {
+[0-9a-f]{32} {
yylval = (char *) new unsigned char[16];
memset (yylval, 0, 16);
- for (int i = 0; i < 32; ++i)
+ int i, j;
+ unsigned char v1, v2;
+ for (i = 0, j = 0; i < 32; i += 2, ++j)
{
- unsigned char val = (unsigned char) yytext[i];
- if (val > '9')
- val = val - 'a' + 10;
- else
- val = val - '0';
- ((unsigned char *) yylval) [i / 2] += val << ((i % 2) ? 0 : 4);
+ v1 = hexnibble((unsigned char) yytext[i+0]);
+ v2 = hexnibble((unsigned char) yytext[i+1]);
+ ((unsigned char *) yylval) [j] = nibbled1(v1, v2);
}
return MD5;
}
-[0123456789abcdef]{128,128} {
+[0-9a-f]{128} {
yylval = (char *) new unsigned char[SHA512_DIGEST_LENGTH];
memset (yylval, 0, SHA512_DIGEST_LENGTH);
- for (int i = 0; i < SHA512_BLOCK_LENGTH; ++i)
+ int i, j;
+ unsigned char v1, v2;
+ for (i = 0, j = 0; i < SHA512_BLOCK_LENGTH; i += 2, ++j)
{
- unsigned char val = (unsigned char) yytext[i];
- if (val > '9')
- val = val - 'a' + 10;
- else
- val = val - '0';
- ((unsigned char *) yylval) [i / 2] += val << ((i % 2) ? 0 : 4);
+ v1 = hexnibble((unsigned char) yytext[i+0]);
+ v2 = hexnibble((unsigned char) yytext[i+1]);
+ ((unsigned char *) yylval) [j] = nibbled1(v1, v2);
}
return SHA512;
}
+[a-zA-Z0-9_-]{86} {
+ /* base64url as defined in RFC4648 */
+ yylval = (char *) new unsigned char[SHA512_DIGEST_LENGTH];
+ memset (yylval, 0, SHA512_DIGEST_LENGTH);
+ int i, j;
+ unsigned char v1, v2, v3, v4;
+ for (i = 0, j = 0; i < 4*(SHA512_DIGEST_LENGTH/3); i += 4, j += 3)
+ {
+ v1 = b64url(((unsigned char) yytext[i+0]));
+ v2 = b64url(((unsigned char) yytext[i+1]));
+ v3 = b64url(((unsigned char) yytext[i+2]));
+ v4 = b64url(((unsigned char) yytext[i+3]));
+ ((unsigned char *) yylval) [j+0] = b64d1(v1, v2, v3, v4);
+ ((unsigned char *) yylval) [j+1] = b64d2(v1, v2, v3, v4);
+ ((unsigned char *) yylval) [j+2] = b64d3(v1, v2, v3, v4);
+ }
+ v1 = b64url((unsigned char) yytext[i+0]);
+ v2 = b64url((unsigned char) yytext[i+1]);
+ v3 = 0;
+ v4 = 0;
+ ((unsigned char *) yylval) [j+0] = b64d1(v1, v2, v3, v4);
+ return SHA512B64URL;
+}
+
\"[^"]*\" { yylval = new char [strlen (yytext+1) + 1];
strcpy (yylval, yytext+1);
yylval[strlen (yylval)-1] = 0;
"Description:" BEGIN (descriptionstate); return DESCTAG;
"Size:" return FILESIZE;
"MD5sum:" return MD5LINE;
+"SHA512:" return SHA512LINE;
"Installed-Size:" return INSTALLEDSIZE;
"Maintainer:" BEGIN (eolstate); return MAINTAINER;
"Architecture:" return ARCHITECTURE;
%token CATEGORY DEPENDS REQUIRES
%token APATH PPATH INCLUDE_SETUP EXCLUDE_PACKAGE DOWNLOAD_URL
%token T_PREV T_CURR T_TEST
-%token SHA512 MD5 INSTALLEDSIZE MAINTAINER PRIORITY
-%token DESCTAG DESCRIPTION FILESIZE ARCHITECTURE SOURCEPACKAGE MD5LINE
+%token SHA512 SHA512B64URL MD5 INSTALLEDSIZE MAINTAINER PRIORITY
+%token MD5LINE SHA512LINE
+%token DESCTAG DESCRIPTION FILESIZE ARCHITECTURE SOURCEPACKAGE
%token RECOMMENDS PREDEPENDS
%token SUGGESTS CONFLICTS REPLACES PROVIDES PACKAGENAME STRTOEOL PARAGRAPH
%token EMAIL COMMA OR NL AT
| DIRECTORY STRING NL { /* TODO */ }
| STANDARDSVERSION STRING NL { /* TODO */ }
| MD5LINE MD5 NL { iniBuilder->buildInstallMD5 ((unsigned char *)$2); }
+ | MD5LINE SHA512 NL { iniBuilder->buildInstallSHA512 ((unsigned char *)$2); }
+ | MD5LINE SHA512B64URL NL { iniBuilder->buildInstallSHA512 ((unsigned char *)$2); }
| SOURCEPACKAGE source NL
| CATEGORY categories NL
| INSTALL STRING { iniBuilder->buildPackageInstall ($2); } installmeta NL
installchksum: /* empty */
| MD5 { iniBuilder->buildInstallMD5 ((unsigned char *)$1);}
| SHA512 { iniBuilder->buildInstallSHA512 ((unsigned char *)$1);}
+ | SHA512B64URL { iniBuilder->buildInstallSHA512 ((unsigned char *)$1);}
;
sourcechksum: /* empty */
| MD5 { iniBuilder->buildSourceMD5 ((unsigned char *)$1); }
| SHA512 { iniBuilder->buildSourceSHA512 ((unsigned char *)$1); }
+ | SHA512B64URL { iniBuilder->buildSourceSHA512 ((unsigned char *)$1); }
;
source /* non-empty */