mirror of
https://github.com/samba-team/samba.git
synced 2025-01-07 17:18:11 +03:00
2765b5c1a2
Hex numbers in IDL are not parsed as numbers, resulting in warnings
like
Argument 0x2000 isn't numeric in numeric lt (<) at /home/douglas/src/samba/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm line 981
not to mention problematic code. We add a utility function to convert
these numbers to numbers.
A typical difference this makes is:
--- old/default/librpc/gen_ndr/ndr_dcerpc.c 2019-11-30 23:40:32.915816967 +1300
+++ new/default/librpc/gen_ndr/ndr_dcerpc.c 2019-11-30 17:00:09.055733660 +1300
@@ -1893,7 +1893,7 @@
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReceiveWindowSize));
- if (r->ReceiveWindowSize > 0x40000) {
+ if (r->ReceiveWindowSize < 8192 || r->ReceiveWindowSize > 262144) {
return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
}
NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
Where the minimum ("0x2000" == 8192) was read as a string, thus
treated as zero.
The treatment as zero was introduced in 142b2a61f8
accidentially, which shows why warnings are important.
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
234 lines
4.1 KiB
Perl
234 lines
4.1 KiB
Perl
###################################################
|
|
# utility functions to support pidl
|
|
# Copyright tridge@samba.org 2000
|
|
# released under the GNU GPL
|
|
package Parse::Pidl::Util;
|
|
|
|
require Exporter;
|
|
@ISA = qw(Exporter);
|
|
@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper genpad parse_int parse_range);
|
|
use vars qw($VERSION);
|
|
$VERSION = '0.01';
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Parse::Pidl::Expr;
|
|
use Parse::Pidl qw(error);
|
|
|
|
=head1 NAME
|
|
|
|
Parse::Pidl::Util - Generic utility functions for pidl
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Parse::Pidl::Util;
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Simple module that contains a couple of trivial helper functions
|
|
used throughout the various pidl modules.
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=over 4
|
|
|
|
=cut
|
|
|
|
=item B<MyDumper>
|
|
a dumper wrapper to prevent dependence on the Data::Dumper module
|
|
unless we actually need it
|
|
|
|
=cut
|
|
|
|
sub MyDumper($)
|
|
{
|
|
require Data::Dumper;
|
|
$Data::Dumper::Sortkeys = 1;
|
|
my $s = shift;
|
|
return Data::Dumper::Dumper($s);
|
|
}
|
|
|
|
=item B<has_property>
|
|
see if a pidl property list contains a given property
|
|
|
|
=cut
|
|
sub has_property($$)
|
|
{
|
|
my($e, $p) = @_;
|
|
|
|
return undef if (not defined($e->{PROPERTIES}));
|
|
|
|
return $e->{PROPERTIES}->{$p};
|
|
}
|
|
|
|
=item B<property_matches>
|
|
see if a pidl property matches a value
|
|
|
|
=cut
|
|
sub property_matches($$$)
|
|
{
|
|
my($e,$p,$v) = @_;
|
|
|
|
if (!defined has_property($e, $p)) {
|
|
return undef;
|
|
}
|
|
|
|
if ($e->{PROPERTIES}->{$p} =~ /$v/) {
|
|
return 1;
|
|
}
|
|
|
|
return undef;
|
|
}
|
|
|
|
=item B<is_constant>
|
|
return 1 if the string is a C constant
|
|
|
|
=cut
|
|
sub is_constant($)
|
|
{
|
|
my $s = shift;
|
|
return 1 if ($s =~ /^\d+$/);
|
|
return 1 if ($s =~ /^0x[0-9A-Fa-f]+$/);
|
|
return 0;
|
|
}
|
|
|
|
=item B<make_str>
|
|
return a "" quoted string, unless already quoted
|
|
|
|
=cut
|
|
sub make_str($)
|
|
{
|
|
my $str = shift;
|
|
if (substr($str, 0, 1) eq "\"") {
|
|
return $str;
|
|
}
|
|
return "\"$str\"";
|
|
}
|
|
|
|
=item B<unmake_str>
|
|
unquote a "" quoted string
|
|
|
|
=cut
|
|
sub unmake_str($)
|
|
{
|
|
my $str = shift;
|
|
|
|
$str =~ s/^\"(.*)\"$/$1/;
|
|
|
|
return $str;
|
|
}
|
|
|
|
=item B<print_uuid>
|
|
Print C representation of a UUID.
|
|
|
|
=cut
|
|
sub print_uuid($)
|
|
{
|
|
my ($uuid) = @_;
|
|
$uuid =~ s/"//g;
|
|
my ($time_low,$time_mid,$time_hi,$clock_seq,$node) = split /-/, $uuid;
|
|
return undef if not defined($node);
|
|
|
|
my @clock_seq = $clock_seq =~ /(..)/g;
|
|
my @node = $node =~ /(..)/g;
|
|
|
|
return "{0x$time_low,0x$time_mid,0x$time_hi," .
|
|
"{".join(',', map {"0x$_"} @clock_seq)."}," .
|
|
"{".join(',', map {"0x$_"} @node)."}}";
|
|
}
|
|
|
|
=item B<ParseExpr>
|
|
Interpret an IDL expression, substituting particular variables.
|
|
|
|
=cut
|
|
sub ParseExpr($$$)
|
|
{
|
|
my($expr, $varlist, $e) = @_;
|
|
|
|
my $x = new Parse::Pidl::Expr();
|
|
|
|
return $x->Run($expr, sub { my $x = shift; error($e, $x); },
|
|
# Lookup fn
|
|
sub { my $x = shift;
|
|
return($varlist->{$x}) if (defined($varlist->{$x}));
|
|
return $x;
|
|
},
|
|
undef, undef);
|
|
}
|
|
|
|
=item B<ParseExprExt>
|
|
Interpret an IDL expression, substituting particular variables. Can call
|
|
callbacks when pointers are being dereferenced or variables are being used.
|
|
|
|
=cut
|
|
sub ParseExprExt($$$$$)
|
|
{
|
|
my($expr, $varlist, $e, $deref, $use) = @_;
|
|
|
|
my $x = new Parse::Pidl::Expr();
|
|
|
|
return $x->Run($expr, sub { my $x = shift; error($e, $x); },
|
|
# Lookup fn
|
|
sub { my $x = shift;
|
|
return($varlist->{$x}) if (defined($varlist->{$x}));
|
|
return $x;
|
|
},
|
|
$deref, $use);
|
|
}
|
|
|
|
=item B<genpad>
|
|
return an empty string consisting of tabs and spaces suitable for proper indent
|
|
of C-functions.
|
|
|
|
=cut
|
|
sub genpad($)
|
|
{
|
|
my ($s) = @_;
|
|
my $nt = int((length($s)+1)/8);
|
|
my $lt = ($nt*8)-1;
|
|
my $ns = (length($s)-$lt);
|
|
return "\t"x($nt)." "x($ns);
|
|
}
|
|
|
|
=item B<parse_int>
|
|
|
|
Try to convert hex and octal strings to numbers. If a string doesn't
|
|
look hexish or octish it will be left as is. If the unconverted string
|
|
is actually a decimal number, Perl is likely to handle it correctly.
|
|
|
|
=cut
|
|
|
|
sub parse_int {
|
|
my $s = shift;
|
|
if ($s =~ /^0[xX][0-9A-Fa-f]+$/) {
|
|
return hex $s;
|
|
}
|
|
if ($s =~ /^0[0-7]+$/) {
|
|
return oct $s;
|
|
}
|
|
return $s;
|
|
}
|
|
|
|
=item B<parse_range>
|
|
|
|
Read a range specification that might contain hex or octal numbers,
|
|
and work out what those numbers are.
|
|
|
|
=cut
|
|
|
|
sub parse_range {
|
|
my $range = shift;
|
|
my ($low, $high) = split(/,/, $range, 2);
|
|
$low = parse_int($low);
|
|
$high = parse_int($high);
|
|
return ($low, $high);
|
|
}
|
|
|
|
|
|
=back
|
|
|
|
=cut
|
|
|
|
1;
|